Skip to content

Commit

Permalink
escape html in input if we are generating tagged output
Browse files Browse the repository at this point in the history
  • Loading branch information
nbogie committed Mar 24, 2013
1 parent 829c46d commit fad5590
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 4 deletions.
1 change: 1 addition & 0 deletions docs/todo.txt
Expand Up @@ -21,6 +21,7 @@ I think when outputting the chords we have to preserve the notation type, so aft
* given a key, report chords in roman numeral form. Start test first. test set will look like:
* sus chords replace the third with a 2nd or 4th. sus on its own means sus4, so Asus9 means Asus4 with a 9th.
* C6, Cm6
* TODO: escape for html all strings from the input, when generating tagged output.

IGNORED:

Expand Down
8 changes: 5 additions & 3 deletions src/Transposer.hs
Expand Up @@ -7,7 +7,7 @@ import ChordParser hiding (main, tests)
import LineSplitter
import Notes
import Test.HUnit
import Utils (bool)
import Utils (bool, escapeHTML)
import Data.Maybe (listToMaybe, fromMaybe)

main :: IO ()
Expand Down Expand Up @@ -111,7 +111,9 @@ printChordSheetLine :: (Symmable a) => PrintFormat -> ChordSheetLine a -> String
printChordSheetLine format line@(ChordSheetLine items orig) =
if lineLooksLikeChords line
then printCSIsAtPositions format items
else orig
else printNonChordLine format orig
where printNonChordLine PlainText = id
printNonChordLine TaggedText = escapeHTML

-- Todo: Improve decision-making over whether a line is chords or not.
-- a single line of text like "Coda:" will wrongly be parsed as a C chord with unrecognised, but carried, detail.
Expand Down Expand Up @@ -152,7 +154,7 @@ generateTextAndHTML = foldl' f ("","")
f :: (PlainString,HtmlString) -> (MarkupElement, String, Pos) -> (PlainString, HtmlString)
f (accText,accHtml) (elemType, word, pos) = (text, html)
where text = accText ++ replicate padLen ' ' ++ word
html = accHtml ++ replicate padLen ' ' ++ spanIt elemType word
html = accHtml ++ replicate padLen ' ' ++ spanIt elemType (escapeHTML word)
padLen = if pos == 0
then 0
else max 1 (pos - length accText)
Expand Down
22 changes: 22 additions & 0 deletions src/Utils.hs
@@ -1,5 +1,8 @@
module Utils where
import qualified Data.IntMap as IntMap
import Data.List (nub)
import Data.Char (ord)

-- bool fold
bool :: a -> a -> Bool -> a
bool t f b = if b then t else f
Expand All @@ -13,3 +16,22 @@ switchRoot newRoot word = newRoot : remRoot word
-- give it the name of a file full only of chords. it will give them all the same root and print with no dupes.
readAndPrintUniqueChords fname = fmap (Data.List.nub . map (switchRoot 'A'). words) (readFile fname) >>= mapM_ putStrLn


-- Lifted directly from Neil Mitchell's Tag Soup
-- | Replace the four characters @&\"\<\>@ with their HTML entities (the list from 'xmlEntities').
escapeHTML :: String -> String
escapeHTML = concatMap esc1
where esc = IntMap.fromList [(b, "&"++a++";") | (a,b) <- xmlEntities]
esc1 x = IntMap.findWithDefault [x] (ord x) esc

-- Lifted directly from Neil Mitchell's Tag Soup
-- | A table mapping XML entity names to code points.
-- Does /not/ include @apos@ as Internet Explorer does not know about it.
xmlEntities :: [(String, Int)]
xmlEntities = let a*b = (a,ord b) in
["quot" * '"'
,"amp" * '&'
-- ,"apos" * '\'' -- Internet Explorer does not know that
,"lt" * '<'
,"gt" * '>'
]
5 changes: 4 additions & 1 deletion testdata/simple
Expand Up @@ -5,10 +5,13 @@ Put him in the long boat 'til he's sober
Put him in the scuppers with the deck pump on him

F#dim CmFoo A/F# Am
What shall we do with the drunken sailor
What shall we <b>do</b> with the drunken sailor

A ha

Coda:
Am7 AM7 Gsus2 Gsus4 A#m7-5 Am/C
Tie him to the taffrail when she's yard-arm under

<script>alert('t3hH4x')</script>

0 comments on commit fad5590

Please sign in to comment.