[Tool] LINE BY LINE

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
SpeedMaster
Posts: 494
Joined: 12 Nov 2016, 16:09

[Tool] LINE BY LINE

07 Feb 2021, 17:16

Hello,
This small utility displays a text one line at a time. :) 8-)
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) 8-) .
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

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: Google [Bot] and 155 guests