<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<!-- Plugin "xirr_mushreader" generated by modification and merge of several existing plugins -->
<!-- Constructed 2022-05-03 -->

<muclient>
<plugin
   name="MushReader"
   author="Tyler Spivey and many others"
   id="925cdd0331023d9f0b8f05a7"
   language="Lua"
   purpose="Plugin for multiple screen readers"
   save_state="y"
   date_written="2022-05-03 17:00:00"
   requires="4.60"
   version="1.2"
   >
</plugin>

<aliases>
  <alias
   match="tts_stop"
   enabled="y"
   send_to="12"
   sequence="100"
  >
    <send>stop()</send>
  </alias>

  <alias
   match="subst *"
   enabled="y"
   script="substfunc"
   sequence="100"
  >
    <send></send>
  </alias>

  <alias
   match="tts_interrupt *"
   enabled="y"
   send_to="12"
   sequence="100"
  >
    <send>
if jfwobject and nvda.jaws_running() then
  jfwobject:SayString("%1", 1)
else
  stop()
  say("%1")
end
    </send>
  </alias>

  <alias
   match="tts_note *"
   enabled="y"
   send_to="12"
   sequence="100"
  >
    <send>say("%1")</send>
  </alias>

  <alias
   script="TTSToggle"
   match="tts"
   enabled="y"
   group="TTS"
   omit_from_command_history="y"
   omit_from_log="y"
   omit_from_output="y"
   sequence="100"
  >
  </alias>

  <alias
   script="TTSFocusToggle"
   match="ftts"
   enabled="y"
   group="TTS"
   omit_from_command_history="y"
   omit_from_log="y"
   omit_from_output="y"
   sequence="100"
  >
  </alias>
</aliases>

<!--  Get our standard constants -->
<include name="constants.lua"/>

<!--  Main script -->
<script>
<![CDATA[
-----------------------------------------
-- general local configuration - run at startup
-----------------------------------------

-- note that because this plugin is configured with "save_state",
-- initializing things here will reset them

require "serialize"
require "tprint"

tts_enabled = true
etts = true
focusnote = false

-- init prior to load of substitutions file
subst={}
subst.status=1

function OnPluginInstall ()
  -- ensure ftts config setting exists
  if (GetVariable("ftts")==nil) then
    SetVariable("ftts",0)
	-- focusnote is a one-time flag to print a help message
    focusnote=true
  end

  -- load substitutions file
  if (FileExists(GetInfo(67).."/settings/substitutions.mushz")==true) then
    dofile(GetInfo(67).."/settings/substitutions.mushz")
  end

  -- make sure we can load the mushreader dll
  assert(package.loadlib("MushReader.dll", "luaopen_audio"))()
  stop()
  say("mush reader initialized")
end

-----------------------------------------
-- helper functions
-----------------------------------------

function tnote(what)
  Execute("tts_note "..what)
end

function say(str)
  nvda.say("       "..str)
end

function stop()
  nvda.stop()
end

function FileExists(filename)
  local file = io.open(filename)
  if file then
    io.close(file)
    return true
  else
    return false
  end
end

-----------------------------------------
-- substitution matcher
-----------------------------------------

function split(str, pat)
  local t = {}
  local fpat = "(.-)" .. pat
  local last_end = 1
  local s, e, cap = str:find(fpat, 1)
  while s do
    if s ~= 1 or cap ~= "" then
      table.insert(t,cap)
    end
    last_end = e+1
    s, e, cap = str:find(fpat, last_end)
  end
  if last_end <= #str then
    cap = str:sub(last_end)
    table.insert(t, cap)
  end
  return t
end

function substfunc(n,l,w)
  act=split(w[1]," ")
  if act[1]=="on" then
    subst.status=1
    tnote("Substitutions on.")
  elseif act[1]=="off" then
    tnote("Substitutions off.")
    subst.status=0
  elseif (act[1]=="remove") then
    w[1]=string.sub(w[1],8)
    if subst[w[1]]==nil then
      Note("No substitution found for the entered text.")
    else
      subst[w[1]]=nil
      Note("Substitution removed!")
      Execute("subst save")
    end
  elseif act[1]=="add" then
    wc=split(w[1],"==")
    wc[1]=string.sub(wc[1],5)
    if wc[2]==nil then
      Note("You must specify a substitution replacement by including 2 equal signs in your command (line==substitute).")
      return
    end
    tnote("OK, substitution added.")
    wc1=wc[1]
    wc2=wc[2]
    subst[wc1]=wc2
    Execute("subst save")
  elseif act[1]=="clear" then
    tnote("cleared!")
    subst={}
    subst.status=1
    Execute("subst save")
  elseif act[1]=="list" then
    tprint(subst)
  elseif act[1]=="save" then
    if not (subst==nil) then
      local vars=GetInfo(67).."/settings/substitutions.mushz"
      local exfw=assert(io.open(vars, "w"))
      exfc=serialize.save_simple(subst)
      assert (exfw:write ("subst="..exfc))
      exfw:close()
    end
    tnote("Saved!")
  else
    tnote("Unrecognized substitutions command. Possible commands are: clear, list, add, remove, on, off")
  end
end

-----------------------------------------
-- TTS toggle
-----------------------------------------

function TTSFocusToggle()
  if GetVariable("ftts")=="0" then
    Note("Speech will now be disabled when switching windows.")
    SetVariable("ftts",1)
  elseif GetVariable("ftts")=="1" then
    Note("Speech will no longer be disabled when switching windows.")
    SetVariable("ftts",0)
  end
end

function TTSToggle (name, line, wc)
  if tts_enabled then
    tts_enabled = false
    etts=false
    stop()
    say("speech off")
  else
    tts_enabled = true
    etts=true
    stop()
    say("speech on")
  end
end

-----------------------------------------
-- OnPlugin event hooks
-----------------------------------------

function OnPluginLoseFocus()
  if (etts==false) then
    return
  end
  if (GetVariable("ftts")=="0") then
    return
  end
  tts_enabled=false
end

function OnPluginGetFocus()
  if focusnote then
    DoAfterSpecial(5,'Note("You can type ftts to control whether mush-z speech should be silenced when switching windows on your computer.")',12)
    focusnote=false
  end
  if (etts==false) then
    return
  end
  if (GetVariable("ftts")=="0") then
    return
  end
  tts_enabled=true
end

function OnPluginTabComplete(word)
  if tts_enabled then
    say(word)
  end
end

-- "t" is type of line, where 0 = output line, 1 = note, 2 = command
function OnPluginScreendraw(t, log, line)
  if not tts_enabled then
    return
  end
  -- checking for an empty string, or a string composed only of spaces.
  -- If we don't, NVDA says blank.
  if (t == 0 or t == 1) and not line:find("^%s*$") then
    if subst.status==0 then
      return
    end
    if subst[line]==nil then
      say(line)
    else
      if (subst[line]=="!skip") then
        return
      else
        say(subst[line])
      end
    end
  end
end

-----------------------------------------
-- function key accelerator setup
-----------------------------------------

Accelerator("ctrl+shift+f12","tts")
]]>            
 </script> 
</muclient>
