M src/Links.hs => src/Links.hs +11 -5
@@ 1,4 1,5 @@
{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables #-}
module Links(extractLinks, linkToText, Link(..), c_extractLinks) where
import Text.XML
@@ 18,7 19,7 @@ import Foreign.StablePtr
import Foreign.C.String
import Foreign.Marshal.Array
import Control.Monad (forM)
-import Control.Exception (catch)
+import Control.Exception (catch, IOException)
import System.Directory -- For locating links.xml, suggestions.gmni
import System.FilePath
@@ 223,16 224,21 @@ updateSuggestions page = do
outputSentences _ "" = return ()
outputSentences links dir = do
Prelude.writeFile (dir </> "sentences.ini") $ unlines sentences
- callProcess "voice2json" ["voice2json", "--profile", dir, "train-profile"]
+ createProcess (proc "voice2json" ["--profile", dir, "train-profile"]){ std_err = NoStream, std_out = NoStream }
+ return ()
+ `catch` \(_ :: IOException) -> return () -- Assume the UI has already warned Voice2Json isn't available.
where
sentences = "[links]" : [
- unwords $ words $ filter validChar line -- Enforce valid sentences.ini syntax.
+ unwords $ words $ map validChar line -- Enforce valid sentences.ini syntax.
| line@(_:_) <- map (unpack . label) links ++ map (unpack . title) links ++ map (show . href) links
]
-- | Can this character appear in a sentences.ini rule without escaping?
- validChar ch = not (isAscii ch) || isSpace ch || isAlphaNum ch
+ validChar ch | not (isAscii ch) || isSpace ch || isAlphaNum ch = ch
+ validChar _ = ' '
--- C API
+------
+--- C API
+------
foreign export ccall c_extractLinks :: StablePtr Page -> CString -> IO (CArray CString)
c_extractLinks c_page c_v2jProfile = do
M src/main.c => src/main.c +6 -7
@@ 5,6 5,7 @@
#include <fcntl.h>
#include <termios.h>
#include <limits.h>
+#include <ctype.h>
#include <dirent.h>
#include <errno.h>
@@ 171,7 172,7 @@ int levenshtein_distance(const char *a, const char* b) {
int deletion_cost = v0[j+1] + 1; // above cell + deletion
int insertion_cost = v1[j] + 1; // left cell + insertion
// top left cell + maybe substitution
- int substitution_cost = v0[j] + (a[i] == b[j] ? 0 : 1);
+ int substitution_cost = v0[j] + (tolower(a[i]) == tolower(b[j]) ? 0 : 1);
v1[j+1] = min(deletion_cost, min(insertion_cost, substitution_cost));
}
@@ 342,10 343,11 @@ int dir_exists(char *path) {
DIR *dir = opendir(path);
if (dir) closedir(dir);
else return ENOENT == errno;
- return 1;
+ return 0;
}
int main(int argc, char **argv) {
+ hs_init(&argc, &argv);
int speak_err = 0;
struct session *session = NULL;
struct page *referer = NULL;
@@ 358,8 360,6 @@ int main(int argc, char **argv) {
FILE *fd_links = NULL;
char *v2j_profile = c_dataDir("voice2json");
- hs_init(&argc, &argv);
-
tcgetattr(0, &stored_settings);
#ifdef WITH_SPEECHD
SPDConnection *spd_conn = NULL;
@@ 467,19 467,18 @@ int main(int argc, char **argv) {
if (use_espeak) speak_err = speak_initialize();
- struct stat sb;
if (validate_v2j_profile && dir_exists(v2j_profile)) {
// TODO Would packagers want a way to configure autodownloading of these profiles?
fprintf(stderr, "Voice2JSON profile is uninitialized! Voice recognition is now disabled.\n");
fprintf(stderr, "Please download a profile from: http://voice2json.org/#supported-languages\n");
- fprintf(stderr, "And save the download in: %s\n", v2j_profile);
+ fprintf(stderr, "And extract the download to: %s\n", v2j_profile);
if (use_espeak) {
speak_text("Voice2JSON profile is uninitialized! Voice recognition is now disabled.",
espeakRATE, 0);
}
v2j_profile = "";
- }
+ } else if (dir_exists(v2j_profile)) v2j_profile = "";
char *ssml, **links, *uri;
int read_links = 0;