Also copy over the implementation of links from pensieve.love.
GZ5WULJVEZJJQPQPSQZE7CEPIYPJ2BJDYUJBMZRA5HLOO7TE3DOQC G54H3YG2NEZPW2F6OYT5JPV7KSKVMNW5D3QT3FBCXTJHAQYTV5UAC S2QMLRXLULVA6M73YVC5VQJ2SYUBHG2DTGXEMOBKEPR4OU7ZKG3AC V5SYDHPQ7IKNLZZ3NJ24FDW3IG4O23AASLP2DTKOBPWUUZ5KUPOAC X3F7ECSLGXCH6NBSDIH7LY47I4EG2RR5VFPEMM6ZVDYQIGFID4HQC 4KC7I3E2DIKLIP7LQRKB5WFA2Z5XZXAU46RFHNFQU5BVEJPDX6UQC BULPIBEGL7TMK6CVIE7IS7WGAHGOSUJBGJSFQK542MOWGHP2ADQQC LF7BWEG4DKQI7NMXMZC4LC2BE5PB42HK5PD6OYBNIDMAZBJASOKQC J2SVGR2EQEROXDDMYZOCELD2VDYQALGZYRSZ4WGMTACAGMRPJ7UAC KKMFQDR43ZWVCDRHQLWWX3FCWCFA3ZSXYOBRJNPHUQZR2XPKWULAC ORRSP7FVCHI2TF5GXBRGQYYJAA3JFYXZBM3T663BKSBV22FCZVCAC ISOFHXB2DX6IRN4HVBYWLADZM7QXQKRNAAS577G542KS4L6G5H3QC KMSL74GAMFNTAKGDKZFP2AMQXUMOC3XH373BO4IABZWBEP3YAXKAC UN7GKYV5YP5DQRKDYNYJTGX3CPXQYBVFJ7SLW44NWCN53VEZ3GAAC H4R5BHVYKFKF2JOFITQ45VEVW32BOWIMHWFOQ35KAUS6QUI7G5QQC R3KXFRZNL4CAT5OSKIIGWR3CHL2YJ5S4TKQDIPEHIJ2HW2WS46BQC B4JEWKWIFIOJ7MIWNDPR3L34NIH4WORBELAWFOPAMWL32SVIJ4YQC OI4FPFINEROK6GNDEMOBTGSPYIULCLRGGT5W3H7VLM7VFH22GMWQC VHQCNMARPMNBSIUFLJG7HVK4QGDNPCGNVFLHS3I4IGNVSV5MRLYQC H6QZ7GRR2UBK4POXP6PNMYHHW54SJAQYTTFVPQK4YIJZ4FECAPPQC 2Y7YH7UPQWDNYDJN4BYY2MOHA36B2BIRX6DMIAKHJPQC7UP2R6NQC 2L5MEZV344TOZLVY3432RHJFIRVXFD6O3GWLL5O4CV66BGAFTURQC for _, f in ipairs(line_cache.fragments) doApp.color(Text_color)select_color(f)local frag_len = utf8.len(f)--? print('text.draw:', f, 'at', line_index,pos, 'after', x,y)
assert(#line_cache.screen_line_starting_pos >= 1)for i=1,#line_cache.screen_line_starting_pos dolocal pos = line_cache.screen_line_starting_pos[i]
-- render fragmentlocal frag_width = App.width(f)if x + frag_width > State.right thenassert(x > State.left) -- no overfull linesy = y + State.line_heightif y + State.line_height > App.screen.height thenreturn y, screen_line_starting_pos
final_screen_line_starting_pos = poslocal f = Text.screen_line(line, line_cache, i)--? print('text.draw:', f, 'at', line_index,pos, 'after', x,y)local frag_len = utf8.len(f)-- render any link decorationsfor _,link_offsets in ipairs(line_cache.link_offsets) dolocal s,e,filename = unpack(link_offsets)local lo, hi = Text.clip_wikiword_with_screen_line(line, line_cache, i, s, e)if lo thenbutton(State, 'link', {x=State.left+lo, y=y, w=hi-lo, h=State.line_height, color={1,1,1},icon = icon.hyperlink_decoration,onpress1 = function()if file_exists(filename) thensource.switch_to_file(filename)endend,})
-- Make [[WikiWords]] (single word, all in one screen line) clickable.local trimmed_word = rtrim(f) -- compute_fragments puts whitespace at the endif starts_with(trimmed_word, '[[') and ends_with(trimmed_word, ']]') thenlocal filename = trimmed_word:gsub('^..(.*)..$', '%1')if source.link_exists(State, filename) thenbutton(State, 'link', {x=x+App.width('[['), y=y, w=App.width(filename), h=State.line_height, color={1,1,1},icon = icon.hyperlink_decoration,onpress1 = function()source.switch_to_file(filename)end,})endendApp.screen.print(f, x,y)
select_color(f)App.screen.print(f, State.left,y)
if line_index == State.cursor1.line thenif pos <= State.cursor1.pos and pos + frag_len > State.cursor1.pos then
if not hide_cursor and line_index == State.cursor1.line thenif pos <= State.cursor1.pos and pos + frag_len >= State.cursor1.pos then
local lo_px = Text.draw_highlight(State, line, x,y, pos, State.cursor1.pos, State.cursor1.pos+utf8.len(State.search_term))
local lo_px = Text.draw_highlight(State, line, State.left,y, pos, State.cursor1.pos, State.cursor1.pos+utf8.len(State.search_term))
Text.draw_cursor(State, x+Text.x(f, State.cursor1.pos-pos+1), y)App.color(Text_color)
Text.draw_cursor(State, State.left+Text.x(f, State.cursor1.pos-pos+1), y)
if Focus == 'edit' and not hide_cursor and State.search_term == nil thenif line_index == State.cursor1.line and State.cursor1.pos == pos thenText.draw_cursor(State, x, y)end
return y, final_screen_line_starting_posendfunction Text.screen_line(line, line_cache, i)local pos = line_cache.screen_line_starting_pos[i]local offset = Text.offset(line.data, pos)if i >= #line_cache.screen_line_starting_pos thenreturn line.data:sub(offset)
for _, f in ipairs(line_cache.fragments) do-- render fragmentlocal frag_width = App.width(f)if x + frag_width > State.right thenx = State.left
-- try to wrap at word boundariesfor frag in line.data:gmatch('%S*%s*') dolocal frag_width = App.width(frag)--? print('-- frag:', frag, pos, x, frag_width, State.width)while x + frag_width > State.width do--? print('frag:', frag, pos, x, frag_width, State.width)if x < 0.8 * State.width then-- long word; chop it at some letter-- We're not going to reimplement TeX here.local bpos = Text.nearest_pos_less_than(frag, State.width - x)-- everything works if bpos == 0, but is a little inefficientpos = pos + bposlocal boffset = Text.offset(frag, bpos+1) -- byte _after_ bposfrag = string.sub(frag, boffset)--? if bpos > 0 then--? print('after chop:', frag)--? endfrag_width = App.width(frag)end--? print('screen line:', pos)
for frag in line.data:gmatch('%S*%s*') dolocal frag_width = App.width(frag)while x + frag_width > State.right doif (x-State.left) < 0.8 * (State.right-State.left) then-- long word; chop it at some letter-- We're not going to reimplement TeX here.local bpos = Text.nearest_pos_less_than(frag, State.right - x)if bpos == 0 then break end -- avoid infinite loop when window is too narrowlocal boffset = Text.offset(frag, bpos+1) -- byte _after_ bposlocal frag1 = string.sub(frag, 1, boffset-1)local frag1_width = App.width(frag1)assert(x + frag1_width <= State.right)table.insert(line_cache.fragments, frag1)frag = string.sub(frag, boffset)frag_width = App.width(frag)endx = State.left -- new lineendif #frag > 0 thentable.insert(line_cache.fragments, frag)
local s, e = 1, 0while s <= #line.data dos, e = line.data:find('%[%[%S+%]%]', s)if s == nil then break endlocal word = line.data:sub(s+2, e-2) -- strip out surrounding '[[..]]'--? print('wikiword:', s, e, word)table.insert(line_cache.link_offsets, {s, e, word})s = e + 1endend-- Intersect the filename between byte offsets s,e with the bounds of screen line i.-- Return the left/right pixel coordinates of of the intersection,-- or nil if it doesn't intersect with screen line i.function Text.clip_wikiword_with_screen_line(line, line_cache, i, s, e)local spos = line_cache.screen_line_starting_pos[i]local soff = Text.offset(line.data, spos)if e < soff thenreturnendlocal eoffif i < #line_cache.screen_line_starting_pos thenlocal epos = line_cache.screen_line_starting_pos[i+1]eoff = Text.offset(line.data, epos)if s > eoff thenreturn