blob: d078bcd8fa5795ac5561a1276079868abfdb9a3f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
|
#!/usr/bin/tclsh
# See COPYING file for copyright and license details.
set usage {tkread [-w] [-m]
-w rewrap lines
-m format markdown text}
# The markdown parsing is inspired by the code of smu:
# <https://github.com/Gottox/smu>
#
# TODO:
# - justify text (not simple; see http://wiki.tcl.tk/1774)
# - add a basic search function
# - add function to type 30g to scroll 30% through an article
# - if window width is small, reduce padx space
# - make scrolling using mouse work even when text area isn't hovered over (also note this sort of scrolling doesn't update the title); integrate the MouseWheel event with scroll. this *should* also fix the issue of dragging and then leaving the window, as the strange scrolling is likely caused by related default behaviour
# - add more markdown processing
set fontfamily {Linux Libertine O}
set fontsize 16
set textcolour #443322
set bgcolour #eeeee2
set outercolour #222222
set inverttextcolour #eeeeee
set invertbgcolour #333030
set invertoutercolour #222222
set inverted 0
set drag 0
set tagnum 0
set domarkdown 0
set surroundfmt { \
{"***" "0" "bold italic"} \
{"**" "0" "bold"} \
{"*" "0" "italic"} \
{"===" "0" "italic"} \
{"==" "3" "italic"} \
{"=" "6" ""} \
}
if { $::argc > 0 && [lindex $::argv 0] == "-h" } {
puts "Usage: $usage"
exit
}
package require Tk
proc rewrap {text} {
set wrapped [regsub -all {\n([^\n])} $text { \1}]
set spaced [regsub -all { *} $wrapped { }]
set better [regsub -all {\n *} $spaced "\n"]
set better [regsub -all {\n} $better "\n\n"]
return [regsub -all {\n\n\n} $better "\n"]
}
# This uses marks before tags, as they handle deletions fine, so
# marks can be made and then the formatting characters can be
# deleted without affecting the position for formatting.
proc markup {widget} {
global surroundfmt
global fontfamily
global fontsize
global tagnum
foreach fmt $surroundfmt {
set searchchar [lindex $fmt 0]
set fmtsizemod [lindex $fmt 1]
set fmtstring [lindex $fmt 2]
set searchlen [string length $searchchar]
set insection 0
set cur ""
set markonnum 0
set markoffnum 0
set cur [$widget search $searchchar 0.0 end]
while {$cur != ""} {
if {$insection == 0} {
set insection 1
$widget mark set markon_$markonnum $cur
incr markonnum
} else {
set insection 0
$widget mark set markoff_$markoffnum $cur
incr markoffnum
}
$widget delete $cur "$cur + $searchlen chars"
set cur [$widget search "$searchchar" $cur end]
}
# ignore any final mismatched mark
if {$markonnum != $markoffnum } {
set markonnum $markoffnum
}
for {set x 0} {$x < $markonnum} {incr x} {
$widget tag add tag_$tagnum markon_$x markoff_$x
}
# TODO: change in changeFontSize too if this works
$widget tag configure tag_$tagnum -font "{$fontfamily} [expr $fontsize + $fmtsizemod] $fmtstring"
incr tagnum
}
}
proc changeFontSize {change} {
global fontfamily
global fontsize
global surroundfmt
global tagnum
set newsize [expr $fontsize $change]
if {$newsize > 0} {
set fontsize $newsize
.t configure -font "{$fontfamily} $fontsize" -padx [expr $fontsize * 3]
for {set x 0} {$x < $tagnum} {incr x} {
set fmtstring [lindex [lindex $surroundfmt $x] 2]
set fmtsizemod [lindex [lindex $surroundfmt $x] 1]
.t tag configure tag_$x -font "{$fontfamily} [expr $fontsize + $fmtsizemod] $fmtstring"
}
}
}
proc invertColours {} {
global inverted
global bgcolour textcolour outercolour
global invertbgcolour inverttextcolour invertoutercolour
if {$inverted} {
set inverted 0
.t configure -bg $bgcolour -fg $textcolour
. configure -bg $outercolour
} else {
set inverted 1
.t configure -bg $invertbgcolour -fg $inverttextcolour
. configure -bg $invertoutercolour
}
}
proc scroll {dir amount} {
.t yview scroll $dir $amount
set percent [expr [lindex [.t yview] 1] * 100]
set rough [regsub {\..*} $percent {}]
wm title . "tkread $rough%"
}
proc doMotion {ypos} {
global lasty
if { $lasty != -1 } {
scroll [expr $lasty - $ypos] pixels
}
set lasty $ypos
}
if { [lsearch [font families] "$fontfamily"] == -1 } {
# A font called "Times" is guaranteed by Tk to be available
set fontfamily Times
}
. configure -bg $outercolour
text .t -font "{$fontfamily} $fontsize" -wrap word -width 64 -padx [expr $fontsize * 3] -bg $bgcolour -fg $textcolour -relief flat
pack .t -expand yes -fill y
set text [read stdin]
foreach arg $::argv {
switch $arg {
-w { set text [rewrap $text] }
-m { set domarkdown 1 }
}
}
.t insert end $text
if { $domarkdown } {
markup .t
}
.t configure -state disabled ;# disable cursor
bind . <Up> {scroll -1 unit}
bind . <k> {scroll -1 unit}
bind . <Down> {scroll 1 unit}
bind . <j> {scroll 1 unit}
bind . <Prior> {scroll -1 page}
bind . <Shift-space> {scroll -1 page}
bind . <Left> {scroll -1 page}
bind . <b> {scroll -1 page}
bind . <K> {scroll -1 page}
bind . <Next> {scroll 1 page}
bind . <space> {scroll 1 page}
bind . <Right> {scroll 1 page}
bind . <J> {scroll 1 page}
bind . <Home> {.t yview moveto 0}
bind . <End> {.t yview moveto 1}
bind . <equal> {changeFontSize +5}
bind . <minus> {changeFontSize -5}
bind . <plus> {changeFontSize +1}
bind . <underscore> {changeFontSize -1}
bind . <v> {invertColours}
bind . <q> {exit}
bind . <ButtonPress-1> {set drag 1; set lasty -1}
bind . <ButtonRelease-1> {set drag 0}
bind . <Motion> {if {$drag} { doMotion %y } }
bind .t <Motion> {set drag 0} ;# so text selection can span lines properly
|