This small utility displays a text one line at a time.
It could be useful for students to memorize small texts such as poems. It can also be used as a tool to teach children to read.
This utility can also load/shuffle a simple quiz file (question/answer) .
You can change some default options in the "default options" section of the script.
The drop down list loads text files from the script directory.
You are free to modify or suggest new improvements
Code: Select all
; =================================================================================================================================
; Name: LINE BY LINE
; Description: Display a text one line at a time.
; credits: Speedmaster
; Topic: https://www.autohotkey.com/boards/viewtopic.php?f=6&t=86640
; Sript version: 1.0
; Tested on: AHK 1.1.31.01 Unicode x32 on WIN 7 64bit
;
; How to play ? :
; Load or paste a text.
; The Drop Down List loads text files from script directory.
; Use the up and down keys to navigate line by line through the text.
; If the text is a quiz you can shuffle the lines by 2 (question/answer) or by 3 lines (question/answser/comment) or by 4 lines (question/hint/answer/comment).
; Press Ctrl or Left to bookmark a line
; Press NumpadAdd to incrase font size
; Press NumpadSub to decrase font size
; ==================================================================================================================================
#SingleInstance force
version:="1.0"
; ============================================== DEFAULT OPTIONS ==========================================================================
fsize:=32 ; default font size
DropDownFolder:=A_ScriptDir ; default drop down folder
DefaultSpeed:=2000 ; the default speed in milisec (autoplay)
div:=1 ; default count lines by 1, 2 or 3 etc...
;==================================================================================================================================
bookmark:=[]
gui, +resize
gui, font, s12
FolderToDLL(DropDownFolder,"m","5")
gui, font, s18, arial bold
gui, add, text, w100 h30 xm y+5 vpage center border, 0/0
gui, add, text, w50 h30 x+5 yp cred vbookmarked center border, % " "
gui, font, s%fsize%, times
h := A_ScreenHeight - 143, w := A_ScreenWidth - 30, yh:=(A_ScreenHeight//2)-150
gui, add, text, readonly x10 w%w% y%yh% vtxt r10 center -border, Please load or paste a text file and use the keyboard arrows `nto navigate line by line through the text.
Menu, FileMenu, Add, &Open, open
Menu, FileMenu, Add, &Reset, Reset
Menu, FileMenu, Add, &Exit, exit
Menu, counterMenu, add, Normal, counter
Menu, counterMenu, add, by 2 lines, counter
Menu, counterMenu, add, by 3 lines, counter
Menu, counterMenu, add, by 4 lines, counter
Menu, counterMenu, add, by 5 lines, counter
menu, shuffleMenu, Add, Normal, shuffle
menu, shuffleMenu, Add, by 2 lines, shuffle
menu, shuffleMenu, Add, by 3 lines, shuffle
menu, shuffleMenu, Add, by 4 lines, shuffle
menu, shuffleMenu, Add, by 5 lines, shuffle
menu, SpeedMenu, Add, 500 msec, speedPlay
menu, SpeedMenu, Add, 1000 msec, speedPlay
menu, SpeedMenu, Add, 1500 msec, speedPlay
menu, SpeedMenu, Add, 2000 msec, speedPlay
menu, SpeedMenu, Add, 2500 msec, speedPlay
menu, SpeedMenu, Add, 3000 msec, speedPlay
menu, PlayMenu, Add, Start, startplay
menu, PlayMenu, Add, Stop, stopplay
menu, PlayMenu, Add, Speed, :SpeedMenu
Menu, HelpMenu, Add, &How to play, howtoplay
Menu, HelpMenu, Add, &About, about
; Create the menu bar by attaching the sub-menus to it:
Menu, MyMenuBar, Add, &File, :FileMenu
Menu, MyMenuBar, Add, &Count, :CounterMenu
Menu, MyMenuBar, Add, &Shuffle, :shuffleMenu
Menu, MyMenuBar, Add, &Play, :Playmenu
Menu, MyMenuBar, Add, &Help, :HelpMenu
; Attach the menu bar to the window:
Gui 1: Menu, MyMenuBar
gui, show, w1200 Maximize, Line By Line v%version%
return
#If WinActive("Line By Line v" version)
^v::
out:=clipboard
out:=RegExReplace(out,"\s*$","") ; remove trailing blank lines
PostMessage, 0x014E, -1, 0, ComboBox1
savedout:=out
lines:=LineVarCount(clipboard)
goto displayline
return
numpadadd::
fsize +=2
Gui, Font, s%fsize%
GuiControl, Font, txt
return
NumpadSub::
fsize -=2
Gui, Font, s%fsize%
GuiControl, Font, txt
return
space::
down::
if (!out)
return
guicontrol,,txt, % displayedLine:=LineStr(out, var:=cyclestr(var, "r:1:" lines,,1,0), 1, "`n")
guicontrol,, bookmarked, % bookmark[var]?"X":""
guicontrol,,page, % (qnum:=ceil(var/div)) "/" lines//div
return
up::
if (!out)
return
guicontrol,,txt, % displayedLine:=LineStr(out, var:=cyclestr(var, "r:1:" lines,,-1,0), 1, "`n")
guicontrol,, bookmarked, % bookmark[var]?"X":""
guicontrol,,page, % (qnum:=ceil(var/div)) "/" lines//div
return
~ctrl::
left::
bookmark[var]:=bookmark[var]?0:1
guicontrol,, bookmarked, % bookmark[var]?"X":""
return
speedPlay:
speed:=A_ThisMenuItemPos*500
HandelCheck()
return
startplay:
play:=true
settimer, play, % (speed>0)?speed:speed:=defaultspeed
return
stopplay:
settimer, play, off
return
pauseplay:
return
play:
if (var=lines) {
play:=0
settimer, play, off
guicontrol,,txt, % LineStr(out, var:=cyclestr(var, "r:1:" lines,,0,0), 1, "`n")
;guicontrol,,page, % var "/" lines
guicontrol,,page, % (qnum:=ceil(var/div)) "/" lines//div
return
}
guicontrol,,txt, % displayedLine:=LineStr(out, var:=cyclestr(var, "r:1:" lines,,1,0), 1, "`n")
guicontrol,,previous, % LineStr(out, var+1, 1, "`n")
guicontrol,,page, % (qnum:=ceil(var/div)) "/" lines//div
return
^o::
open:
filepath:=""
FileSelectFile, filepath
if !filepath
return
PostMessage, 0x014E, -1, 0, ComboBox1
open2:
fileread, out, % filepath
out:=RegExReplace(out,"\s*$","") ; remove trailing blank lines
savedout:=out
lines:=LineVarCount(out)
displayline:
lines:=LineVarCount(out)
var:=1
guicontrol,,txt, % displayedLine:=LineStr(out, var:=cyclestr(var, "r:1:" lines,,-1,0), 1, "`n")
updatecounter:
guicontrol,,page, % (qnum:=ceil(var/div)) "/" lines//div
return
tooltip:
(time>10) && (speed:=time)
time:=""
tooltip,
return
GuiSize:
if ErrorLevel = 1 ; The window has been minimized. No action needed.
return
NewWidth := A_GuiWidth - 20
NewYpos := A_GuiHeight//2 -100
(NewYpos<0) && NewYpos:=0
GuiControl, Move, txt, w%NewWidth% y%NewYpos%
GuiControl, MoveDraw, txt
return
SelectedItem:
gui, submit, nohide
filepath:=DropDownFolder . "\" . MyFavoriteFolder
goto open2
return
Howtoplay:
msgbox, % "Load or paste a text. `nUse the up and down keys to navigate line by line through the text.`n`nIf the text is a quiz you can shuffle the lines by 2 (question/answer) or by 3 lines (question/answser/comment) or by 4 lines (question/hint/answer/comment).`n`nThe Drop Down List loads text files from script directory.`n`nPress Ctrl or Left to add a bookmark`n`nPress NumpadAdd to incrase font size`nPress NumpadSub to decrase font size"
return
about:
msgbox, Line By Line v%version% `nby Speedmater
return
reset:
out:=savedout
var:=1
goto displayline
return
shuffle:
bookmark:=[]
guicontrol,, bookmarked, % ""
out:=savedout
var:=1
div:=A_ThisMenuItemPos
out:=stjumble(out, A_ThisMenuItemPos)
HandelCheck()
goto displayline
return
counter:
div:=A_ThisMenuItemPos
HandelCheck()
goto updatecounter
return
exit:
ExitApp
return
guiclose:
~esc::
exitapp
return
HandelCheck(){
Menu, % A_ThisMenu, UseErrorLevel
Loop 10
Menu, % A_ThisMenu, UnCheck, %a_index%&
Menu, % A_ThisMenu, Check, %A_ThisMenuItem%
}
LineVarCount(var) {
Loop Parse, var, `n, `r
max := A_Index
return max
}
LineStr(ByRef S, P, C:="", D:="") { ; LineStr v0.9c, by SKAN on D341/D34M @ tiny.cc/linestr
Local L := StrLen(S), DL := StrLen(D:=(D ? D : Instr(S,"`r`n") ? "`r`n" : "`n") ), F, P1, P2
Return SubStr(S,(P1:=L?(P!=1&&InStr(S,D,,0))?(F:=InStr(S,D,,P>0,Abs(P-1)))?F+DL:P-1<1?1:0:(F:=1)
:0),(P2:=(P1&&C!=0)?C!=""?(F:=InStr(S,D,,(C>0?F+DL:0),Abs(C)))?F-1:C>0?L:1:L:0)>P1?P2-P1+1:0)
}
CycleStr(S:="", Z:="", D:="|", dir:=1, cycle:=true) {
if (regexmatch(z, "i)R:? ?(-?\d+):(-?\d+)", num)) {
--num1
while (num1++ < num2)
numrange .= num1 (D?D:D:="|")
z:=rtrim(numrange, (D?D:D:="|"))
}
oz:=strsplit(z, d), ozb:=[]
for k, v in oz
ozb[v,1]:=oz[(K+1)<=oz.length()?(k+1):1], ozb[v,2]:=oz[(k-1)>0?(k-1):oz.length()]
if (dir=0)
return ozb[oz[oz.length()],1] ; start of list dir=0
if (dir=2)
return ozb[oz.1,2] ; end of list dir=2
if (!cycle && (dir>0) && (s=oz[oz.length()])) || (!cycle && (dir=-1) && (s=oz[1])) ; cycle disabled
return s
else
return, ozb[ozb[s].length()?s:oz[oz.length()]][(dir=-1)?2:1] ; next dir=1 or previous dir=-1
}
stjumble(Text, Weight=1, Delim = "`n", Omit = "")
{
If (StrLen(Text) <= 1) ; added safety check ...
Return Text
Text0:=1
Loop, Parse, Text, %Delim%, %Omit%
{
If (Mod(A_Index,Weight) = 1 || Weight=1)
Text0++
Text%Text0% .= A_LoopField Delim
}
Loop, % Text0
NewOrder .= A_Index "|"
NewOrder:=Trim(NewOrder,"|")
OldOrder:=NewOrder
Loop
{
Sort, NewOrder, Random D|
If (NewOrder != OldOrder)
Break
}
Loop, parse, NewOrder, |
Output .= Text%A_LoopField%
Return Trim(Output,Delim)
}
FolderToDLL(folder, x:="+10", y:="p") {
global MyFavoriteFolder
Gui, Add, DropDownList , x%x% y%y% w160 gselecteditem vMyFavoriteFolder
Loop, %Folder%\*.txt
GuiControl, , MyFavoriteFolder, %A_LoopFileName%
}
Example of a simple quiz (you can copy and paste the text directly in the GUI)
Spoiler