It is currently October 14th, 2024, 11:24 pm

Quote plugin alternative - Quotes

Quote of the Day, To-Do List and other text-based skins
User avatar
jsmorley
Developer
Posts: 22856
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Quote plugin alternative - Quotes

Post by jsmorley »

One of the slight issues with the Quote plugin is that it generates a new random number each time it is updated, so depending on what you are using as a resource (files in a folder or lines in a text file) each call to the plugin is treated as a brand-new random search of the resource, and no attempt is made to ensure that an item is not "repeated" until all items have been used.

The fewer the number of items in total, the more likely it is to repeat one, but there is never any guarantee, just the "odds", that it won't.

This quote skin shows how you can use a Lua script to overcome this minor limitation. What it will do is read in a text file containing any number of quotes, will provide a random quote on each update, and keep track of what has already been used so it won't repeat any of them until all of them have been displayed.
RandomQuote_1.0.rmskin
RandomQuote.jpg
RandomQuote.ini

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
OnRefreshAction=[!SetOption MeterQuote W "#WidthVar#@#Monitor##"][!SetOption MeterQuote X "(#WidthVar#@#Monitor##/2)"][!UpdateMeter MeterQuote][!Redraw]

[Metadata]
Name=RandomQuote
Author=JSMorley
Description=Pithy quote every 30 seconds, centered on the monitor.
Instructions=Click to copy to clipboard||Double-click text to open text file with quotes.  Middle click to refresh.||Set variable "Monitor" to the number of the monitor displayed on.
Version=Mar 18, 2013
License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0

[Variables]
Monitor=2
SecondsBetween=30
WidthVar=#SCREENAREAWIDTH
FontFace=Trebuchet MS
FontSize=11
FontColor=255,255,255,255

[MeasureQuote]
Measure=Script
ScriptFile=RandomQuote.lua
UpdateDivider=#SecondsBetween#

[MeterQuote]
Meter=String
MeasureName=MeasureQuote
FontColor=#FontColor#
FontFace=#FontFace#
FontSize=#FontSize#
StringStyle=Normal
StringAlign=Center
SolidColor=0,0,0,1
AntiAlias=1
LeftMouseUpAction=[!SetClip "[MeasureQuote]"]
LeftMouseDoubleClickAction=["#CURRENTPATH#Pithy.txt"]
MiddleMouseUpAction=!Refresh
DynamicVariables=1
RandomQuote.lua

Code: Select all

function Initialize()
   
	quoteTable, currentTable = {}, {}
   
	for line in io.lines(SKIN:MakePathAbsolute('Pithy.txt')) do
		table.insert(quoteTable, line)
	end
   
end -- Initialize

function Update()

	if #currentTable == 0 then
		currentTable = SortRandom(quoteTable)
	end
	
	return table.remove(currentTable)
   
end -- Update

function SortRandom(inputTable)

	assert(type(inputTable) == 'table', ('SortRandom must receive a table. Received %s instead.'):format(type(inputTable)))

	local sortedTable, unsortedTable = {}, {}
	
	for inc = 1, #inputTable do
		table.insert(unsortedTable, inputTable[inc])
	end

	math.randomseed(tonumber(tostring(os.time()):reverse():sub(1,6)))

	while #unsortedTable > 0 do
		table.insert(sortedTable, table.remove(unsortedTable, math.random(1, #unsortedTable)))
	end
	
	unsortedTable = nil

	return sortedTable
	
end -- SortRandom
What the Lua does is:

- In Initialize(), read the entire text file being used as the source into a table. Get the count of how many items are in the table.

- Create a table (quoteTable) to hold the random numbers, between 1 and the total number of quotes, that have already been used.

- in Update(), check to see if a temporary table (currentTable) created to hold the quotes in a random order is empty.

- If so - Execute the RandomSort() function which will create the temporary table by copying the quotes from quoteTable into it in a random order.

- Remove and return the first quote from the temporary / random table to the skin, for display in the meter.

Each of the quotes will be used in a random order, never repeating until all of them have been used. Then it will start over. Feel free to ask any questions about how / what this is doing.
You do not have the required permissions to view the files attached to this post.
User avatar
jsmorley
Developer
Posts: 22856
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Quote plugin alternative - Quotes

Post by jsmorley »

This is very similar to a skin JSQuotes I had posted about before, but with more efficient Lua code worked out between Smurfier and myself.
boober
Posts: 1
Joined: January 7th, 2018, 8:14 pm

Re: Quote plugin alternative - Quotes

Post by boober »

Hi jsmorley,

Thanks so much for this skin. Is there a way for this to display multi-line quotes as a single quote? I've searched the forums for solutions, most of which apply to using QuotePlugin measures, and I'm not at all familiar with Lua scripts. (Though I did snip from other solutions you've posted to get the file to read from another drive location. Woo hoo!)

A few of your solutions involve adding different parts of the quote to an array and then feeding that array into a random quote selection. However, this script uses a table and not an array and I like the simplicity of using a table. Is there any equivalent to the QuotePlugin Separator measure here that would make this a simple solution?

Any help would be appreciated.
CrimsonEnigma
Posts: 1
Joined: November 5th, 2023, 5:30 pm

Re: Quote plugin alternative - Quotes

Post by CrimsonEnigma »

Hi boober,

Probably you arent around this website anymore but I found what you wanted and I figured maybe someone else is looking for an answer too.

In file RandomQuote.ini in the last [MeterQuote] you need to put

Code: Select all

ClipString=2
ClipStringH=1000
ClipStringW=1000
ClipString H: https://docs.rainmeter.net/manual/meters/string/#ClipStringH
Sets a maximum width that the meter will expand to accommodate the string when ClipString=2. This setting is ignored if the W option is set.

ClipString W: https://docs.rainmeter.net/manual/meters/string/#ClipStringW
Sets a maximum height that the meter will expand to accommodate the string when ClipString=2. This setting is ignored if the H option is set.
so the final code would be:

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
OnRefreshAction=[!SetOption MeterQuote W "#WidthVar#@#Monitor##"][!SetOption MeterQuote X "(#WidthVar#@#Monitor##/2)"][!UpdateMeter MeterQuote][!Redraw]

[Metadata]
Name=RandomQuote
Author=JSMorley
Description=Pithy quote every 30 seconds, centered on the monitor.
Instructions=Click to copy to clipboard||Double-click text to open text file with quotes.  Middle click to refresh.||Set variable "Monitor" to the number of the monitor displayed on.
Version=Mar 18, 2013
License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0

[Variables]
Monitor=1
SecondsBetween=120
WidthVar=#SCREENAREAWIDTH
FontFace=Trebuchet MS
FontSize=11
FontColor=255,255,255,255

[MeasureQuote]
Measure=Script
ScriptFile=RandomQuote.lua
UpdateDivider=#SecondsBetween#

[MeterQuote]
Meter=String
MeasureName=MeasureQuote
FontColor=#FontColor#
FontFace=#FontFace#
FontSize=#FontSize#
StringStyle=Normal
StringAlign=Center
SolidColor=0,0,0,1
AntiAlias=1
LeftMouseUpAction=[!SetClip "[MeasureRandom]"]
LeftMouseDoubleClickAction=["#CURRENTPATH#Pithy.txt"]
MiddleMouseUpAction=!Refresh
DynamicVariables=1
ClipString=2
ClipStringH=1000
ClipStringW=1000
Note: play around with the value to find out which one suits best your needs.

Cheers!