defmodule Say do @moduledoc """ Lets the System say a given text via text-to-speech. ## Configuration (How to say something) You can configure the way how to say something... via an elixir function: config :say, func: &IO.inspect/1 via shell command: config :say, exec: "say" config :say, exec: "say" exec_args: "-v somevoice" via shell command over an SSH tunnel: config :say, exec: "say", ssh_args: ~w(-p 2222 localhost) config :say, exec: "say", exec_args: "-v somevoice" ssh_args: ~w(-p 2222 localhost) ## OS specialities * On the Mac the executable `say` can be used directly. * On Linux I haven't tried, but these should work [https://linuxhint.com/command-line-text-speech-apps-linux/](https://linuxhint.com/command-line-text-speech-apps-linux/) """ @doc """ Lets the system say the given text. ## Examples iex> Say.say("hello") """ def say(text) do do_say(text, Application.get_env(:say, :func), Application.get_env(:say, :exec), Application.get_env(:say, :exec_args), Application.get_env(:say, :ssh_args) ) end defp do_say(text, func, exec, _exec_args, ssh_args) when func != nil and exec == nil and ssh_args == nil do func.(text) end defp do_say(text, func, exec, exec_args, ssh_args) when func == nil and exec != nil and exec_args != nil and ssh_args == nil do cmd = exec args = exec_args ++ [text] |> Enum.reject(&is_nil/1) do_system_cmd(cmd, args) end defp do_say(text, func, exec, exec_args, ssh_args) when func == nil and exec != nil and exec_args == nil and ssh_args == nil do cmd = exec args = [text] do_system_cmd(cmd, args) end defp do_say(text, func, exec, exec_args, ssh_args) when func == nil and exec != nil and ssh_args != nil do cmd = "ssh" exec_args = if exec_args != nil, do: exec_args, else: [] args = ssh_args ++ [exec] ++ exec_args ++ [text] |> Enum.reject(&is_nil/1) do_system_cmd(cmd, args) end defp do_say(_text, _func, _exec, _exec_args, _ssh_args) do raise RuntimeError, message: "see config samples" end defp do_system_cmd(cmd, args) do if Application.get_env(:say, :test) do {cmd, args} else System.cmd(cmd, args) end end end