From df3c5bae24837b144a1f09d06d4cad90b8905915 Mon Sep 17 00:00:00 2001 From: Martin Peach Date: Thu, 21 Feb 2013 16:28:13 +0000 Subject: Example class that splits a text file into sentences. svn path=/trunk/externals/loaders/pdlua/; revision=17050 --- examples/ltextfile-drip.pd_lua | 230 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 examples/ltextfile-drip.pd_lua (limited to 'examples/ltextfile-drip.pd_lua') diff --git a/examples/ltextfile-drip.pd_lua b/examples/ltextfile-drip.pd_lua new file mode 100644 index 0000000..16a1651 --- /dev/null +++ b/examples/ltextfile-drip.pd_lua @@ -0,0 +1,230 @@ +--[[ +-- ltextfile-drip +-- Output a text file as a sequence of symbols (sentences) +-- author Martin Peach 20120913 +--]] + +-- Pd class + +local LTextFileDrip = pd.Class:new():register("ltextfile-drip") +local file ourTextFile = nil +local words = {} +local wordIndex = 0 +local playbackIndex = 0 +local ourSentence, ourRemainingLine = nil +local ourLine = nil + +function LTextFileDrip:initialize(name, atoms) +--pd.post("LTextFileDrip:initialize-> name is " .. name); +--pd.post("number of atoms is ".. #atoms) +--for i,v in ipairs(atoms) do +-- pd.post(i .. " = " .. v) +--end + if #atoms > 0 then self:openOurTextFile(atoms[1]) end + if ourTextFile == nil then pd.post("LTextFileDrip:initialize: unable to open " .. atoms[1]) end + self.inlets = 1 + self.outlets = 3 + return true +end + +-- LTextFileDrip:openOurTextFile: open a text file using name as a path +function LTextFileDrip:openOurTextFile(name) + if ourTextFile ~= nil then +--pd.post("LTextFileDrip:openOurTextFile: closing old file") + ourTextFile:close() + ourTextFile = nil + end +--pd.post("LTextFileDrip:openOurTextFile ( " .. name .. " )") + ourTextFile = io.open(name) + if ourTextFile == nil then + pd.post("LTextFileDrip:openOurTextFile: Unable to open " .. name) + end + ourRemainingLine = nil +end + +function LTextFileDrip:rewindOurTextFile() +-- pd.post("LTextFileDrip:rewind") + if ourTextFile == nil then + pd.post("LTextFileDrip:rewindOurTextFile: no open file") + else + ourTextFile:seek("set") --sets the position to the beginning of the file (and returns 0) + wordIndex = 0 + playbackIndex = 0 + end +end + +-- LTextFileDrip:drip: accumulate a line of words from ourTextFile and output them as symbols, one per bang +function LTextFileDrip:drip() + local ourPunc + local repeatCount = 0 + + if ourTextFile == nil then + pd.post("LTextFileDrip:drip: no open file") + return + end +-- if wordIndex == 0 then -- read another line + repeat + repeatCount = repeatCount + 1 +--pd.post("repeat number " .. repeatCount) + if ourRemainingLine == nil then +--pd.post ("1> ourRemainingLine is nil") + ourLine = ourTextFile:read() + if ourLine == nil then + self:outlet(3, "bang", {}) -- end of file + return + end +--pd.post ("1> ourLine is [" .. ourLine .. "] len: " .. ourLine:len()) + -- strip CR LF + s,e = ourLine:find("[\n\r]") + if s then +--pd.post("1> CR or LF at " .. s) + ourLine = ourLine:sub(1,s-1) .. " " + else + ourLine = ourLine .. " " + end + elseif ourRemainingLine:len() == 0 then -- read another line +--pd.post ("2> ourRemainingLine length 0") + ourLine = ourTextFile:read() + if ourLine == nil then + self:outlet(3, "bang", {}) -- end of file + return + end +--pd.post ("2> ourLine is [" .. ourLine .. "] len: " .. ourLine:len()) + s,e = ourLine:find("[\n\r]") + if s then +--pd.post("2> CR or LF at " .. s) + ourLine = ourLine:sub(1,s-1) .. " " + else + ourLine = ourLine .. " " + end +--pd.post("Not setting ourLine from ourRemainingLine, whose length is precisely " .. ourRemainingLine:len()) + else + cstart,cend = ourRemainingLine:find("[,.;!?:]") + if cstart == nil then -- no punctuation in remainingLine, add next line from ourTextFile +--pd.post("3> Adding a new line to ourRemainingLine") + ourLine = ourTextFile:read() + if ourLine == nil then -- no more lines + self:outlet(3, "bang", {}) -- end of file + return + end +--pd.post ("3> ourLine is [" .. ourLine .. "] len: " .. ourLine:len()) + s,e = ourLine:find("[\n\r]") + if s then +--pd.post("3> CR or LF at " .. s) + ourLine = ourLine:sub(1,s-1) .. " " + else + ourLine = ourLine .. " " + end + --ourLine = ourLine:gsub("[\n\r]", " ") + if (ourLine:len() == 1) then -- an empty line +--pd.post("BLANK LINE (1)") + ourLine = "." -- replace blank line with punctuation to force a chop + end + ourLine = ourRemainingLine .. ourLine + else -- remainingLine has punctuation +--pd.post("4> ourRemainingLine contains punctuation") + ourLine = ourRemainingLine + end + ourRemainingLine = nil + end -- if ourRemainingLine == nil + ourPunc = nil + if ourLine ~= nil then -- line has content + if ourLine:len() > 0 then + wordIndex = 0 +--pd.post("LTextFileDrip:drip: <" .. ourLine .. ">") +--pd.post("LTextFileDrip:drip: len" .. ourLine:len()) +--pd.post("LTextFileDrip:drip: 1st char" .. ourLine:byte(1)) + if ((ourLine:len() == 1) and (ourLine:byte(1) == 13)) then -- a blank line +--pd.post("BLANK LINE (2)") + ourSentence = ourRemainingLine + ourRemainingLine = nil + else -- find a comma, period, semicolon, exclamation or question mark + cstart,cend = ourLine:find("[,.;!?:]") + if cstart ~= nil then -- take the line before the mark +--pd.post("LTextFileDrip:drip: cstart " .. string.format ('%d', cstart) .. " cend " .. string.format('%d', cend)) + ourPunc = ourLine:sub(cend, cend) +--pd.post("LTextFileDrip:drip: punctuation: " .. ourPunc) + ourSentence = ourLine:sub(1, cend) -- leave punctuation + if ourRemainingLine ~= nil then + ourSentence = ourRemainingLine .. ourSentence + end + ourRemainingLine = ourLine:sub(cend+1) +--pd.post("LTextFileDrip:drip punctuation found: ourSentence is " .. ourSentence) +--pd.post("LTextFileDrip:drip punctuation found: ourRemainingLine is " .. ourRemainingLine) + else -- no mark, take the whole line + if ourRemainingLine ~= nil then + ourRemainingLine = ourRemainingLine .. ourLine +--pd.post("LTextFileDrip:drip more to come: ourRemainingLine is " .. ourRemainingLine) +--for c = 1, ourRemainingLine:len() do pd.post("_" .. ourRemainingLine:byte(c) .. "_") end + else + ourRemainingLine = ourLine +--pd.post("LTextFileDrip:drip first: ourRemainingLine is " .. ourRemainingLine) + end + end -- if cstart ~= nil + end -- if ((ourLine:len() == 1) and (ourLine:byte(1) == 13)) + end -- if ourLine:len() > 0 + if ourSentence ~= nil then + if ourSentence:gmatch("%w+") then + if ((ourSentence:len() == 1) and (ourSentence:byte(1) <= 32)) then +--pd.post("BLANK LINE (3)") + wordIndex = 0 -- skip blank line + else + wordIndex = 1 + end +-- for w in ourSentence:gmatch("%w+") do +-- wordIndex = wordIndex + 1 +-- words[wordIndex] = w +--pd.post("wordIndex " .. wordIndex .. " for length " .. ourSentence:len() .. " starts with " .. ourSentence:byte(1)) + end + end + playbackIndex = 1 + else -- bang through outlet 3 serves as end of file notification + self:outlet(3, "bang", {}) + end -- if ourLine ~= nil +-- end + until ((wordIndex ~= 0) or (ourLine == nil)) + if ourPunc ~= nil then + self:outlet(2, "symbol", {ourPunc}) -- output punctuation + end + if wordIndex > 0 then -- output sentence as a single symbol + if ourSentence ~= nil then + len = ourSentence:len() +--pd.post ("ourSentence:len() is " .. len) + if len > 0 then +--pd.post("ourSentence is not zero-length") +--pd.post("ourSentence [" .. ourSentence .. "]") +--pd.post("starts with " .. ourSentence:byte(1)) + self:outlet(1, "symbol", {ourSentence}) -- output entire line + else +--pd.post("ourSentence is zero-length") + self:outlet(1, "bang", {}) -- an empty line + end + end + wordIndex = 0 -- no more words + ourSentence = nil -- no more sentence + end +end + +function LTextFileDrip:in_1(sel, atoms) -- anything +-- pd.post("LTextFileDrip:in-> sel is " .. sel); +-- pd.post("number of atoms is ".. #atoms) +-- for i,v in ipairs(atoms) do +-- pd.post(i .. " = " .. v) +-- end + + if sel == "bang" then -- output the next sentence + self:drip() + elseif sel == "open" then -- open a file + self:openOurTextFile(atoms[1]) + elseif sel == "rewind" then -- rewind the file + self:rewindOurTextFile() + elseif sel == "symbol" then -- assume it's a file name + self:openOurTextFile(atoms[1]) + elseif #atoms == 0 then -- a selector + self:error("LTextFileDrip:in_1: input not known") + else -- reject non-symbols + self:error("LTextFileDrip:in_1: input not a symbol or bang") + end +end +-- end of ltextfile-drip + -- cgit v1.2.1