M src/Links.hs => src/Links.hs +25 -0
@@ 6,6 6,7 @@ import qualified Data.Map as M
import Network.MIME.Info as MIME
import Network.URI
import Data.Text (Text, unpack, append, pack, replace, strip)
+import qualified Data.Text.Lazy as LTxt
import qualified Data.Text.Foreign as FTxt
import Data.Maybe
@@ 190,3 191,27 @@ c_extractLinks c_page = do
newArray0 nil $ concat ret
text2cstring txt = FTxt.withCStringLen txt $ \s -> (peekCStringLen s >>= newCString)
+
+foreign export ccall c_formatLink :: CString -> CString -> CString -> IO CString
+
+c_formatLink c_label c_title c_url = do
+ label <- ctext c_label
+ title <- ctext c_title
+ url <- ctext c_url
+
+ sfx <- getXdgDirectory XdgCache "rhapsode"
+ let bulletpoint_el = audio (sfx </> "bulletpoint.wav")
+ let label_el = prosody [("pitch", "low")] label
+ let title_el = prosody [("volume", "soft")] title
+ let link_el = audio (sfx </> "link.wav")
+ let url_el = style "punctuation" "all" $ style "capital_letters" "pitch" $ prosody [("rate", "fast")] url
+ let root = el "speak" [] $ map NodeElement [bulletpoint_el, label_el, title_el, link_el, url_el]
+
+ let ssml = renderText def $ Document (Prologue [] Nothing []) root []
+ newCString $ LTxt.unpack ssml
+ where
+ ctext cstr = pack <$> peekCString cstr
+ el name attrs childs = Element name (M.fromList attrs) childs
+ audio src = el "audio" [("src", pack src)] []
+ prosody attrs txt = el "prosody" attrs [NodeContent txt]
+ style field mode inner = el "tts:style" [("field", field), ("mode", mode)] [NodeElement inner]
M src/Render.hs => src/Render.hs +0 -4
@@ 181,7 181,3 @@ c_renderDoc c_session c_page rewriteURLs = do
B.toStrict ssml `useAsCString` \cstr -> do
str <- peekCString cstr
newCString str
-
-foreign export ccall c_cachedir :: IO CString
-
-c_cachedir = Dir.getXdgDirectory Dir.XdgCache "rhapsode" >>= newCString
M src/main.c => src/main.c +4 -3
@@ 34,6 34,7 @@ char *c_renderDoc(struct session*, struct page*, _Bool);
char **c_extractLinks(struct page*);
char **c_docLinksAndRendering(struct session*, struct page*, _Bool); // FIXME segfaults.
int c_ssmlHasMark(char*, char*);
+char *c_formatLink(char *label, char *title, char *url);
char *c_lastVisited(char*);
@@ 215,9 216,9 @@ char *select_link(char **links, char *command) {
// Communicate
printf("%s\t%s\t%s\n", links[i+2], links[i], links[i+1]);
- speak_text(links[i+2], espeakRATE, 20); // URL, fast
- speak_text(links[i], espeakPITCH, -40); // Label, low
- speak_text(links[i+1], espeakVOLUME, -40); // Title, quite
+ char *ssml = c_formatLink(links[i], links[i+1], links[i+2]);
+ speak(ssml, NULL, NULL);
+ free(ssml);
}
return NULL;