From dfd21b695107fc01941e3218b60d360ee38fb150 Mon Sep 17 00:00:00 2001 From: Jeffrey Armstrong Date: Tue, 28 Apr 2020 20:55:15 -0400 Subject: Links are now rendered in the dumb renderer. Preparation sub now available before every layout is performed. --- dumb_render.f90 | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++- layout.f90 | 5 +++ render.f90 | 64 ++++++++++++++++++++++++++++++++++++ samples/sample1.gmi | 3 ++ 4 files changed, 164 insertions(+), 1 deletion(-) diff --git a/dumb_render.f90 b/dumb_render.f90 index f50efe1..7832891 100644 --- a/dumb_render.f90 +++ b/dumb_render.f90 @@ -2,11 +2,18 @@ module dumb_render use render implicit none + integer, parameter::width = 79 + integer, parameter::height = 24 + type, extends(renderer) :: dumb_renderer + integer::link_index + character(len=1024), dimension(height)::link_urls + contains procedure :: initialize => dumb_initialize + procedure :: prepare_for_layout => prepare_for_dumb_layout procedure :: text_width => dumb_text_width procedure :: text_height => dumb_text_height @@ -20,6 +27,12 @@ implicit none procedure :: draw_preformatted => dumb_text_draw + procedure :: link_width => dumb_link_width + procedure :: link_height => dumb_text_height + procedure :: is_link_visible => dumb_text_visible + + procedure :: draw_link => dumb_link_draw + end type dumb_renderer contains @@ -29,11 +42,41 @@ contains class(dumb_renderer)::self - self%max_width = 79 + self%max_width = width self%y = 0 + self%link_index = 0 + self%link_urls = " " + end subroutine dumb_initialize + subroutine prepare_for_dumb_layout(self) + implicit none + + class(dumb_renderer)::self + + self%link_index = 0 + self%link_urls = " " + + ! Write a page feed to clear the screen (not really necessary, but...) + write(*, '(A1)', advance='no') char(12) + + end subroutine prepare_for_dumb_layout + + function store_link(self, url) + implicit none + + class(dumb_renderer)::self + character(*), intent(in)::url + integer::store_link + + self%link_index = self%link_index + 1 + self%link_urls(self%link_index) = url + + store_link = self%link_index + + end function store_link + function dumb_text_width(self, text) implicit none @@ -90,4 +133,52 @@ contains end subroutine dumb_text_draw + function build_link_text(self, text, idnum) result(res) + implicit none + + class(dumb_renderer)::self + character(*), intent(in)::text + integer, intent(in)::idnum + character(width)::res + + write(res, '(A1, I3, A2)') '[', idnum,'][' + + if(len_trim(text) < (width - 7)) then + res = trim(res)//trim(text)//']' + else + res = trim(res)//text(1:(width-7))//']' + end if + + end function build_link_text + + function dumb_link_width(self, text) + implicit none + + class(dumb_renderer)::self + character(*), intent(in)::text + integer::dumb_link_width + + character(width)::link + + link = build_link_text(self, text, 0) + + dumb_link_width = dumb_text_width(self, link) + + end function dumb_link_width + + subroutine dumb_link_draw(self, text, url) + implicit none + + class(dumb_renderer)::self + character(*), intent(in)::text, url + integer::i + character(width)::link + + i = store_link(self, url) + link = build_link_text(self, text, i) + + call dumb_text_draw(self, link) + + end subroutine dumb_link_draw + end module dumb_render \ No newline at end of file diff --git a/layout.f90 b/layout.f90 index 5d6f200..1c7d8cb 100644 --- a/layout.f90 +++ b/layout.f90 @@ -28,6 +28,8 @@ contains walker => first_line laying_out = .true. + call rendering_engine%prepare_for_layout() + do while(laying_out) select case (walker%line_type) @@ -36,6 +38,9 @@ contains case (line_type_preformatted) call render_preformatted(rendering_engine, walker%text) + + case (line_type_link) + call render_link(rendering_engine, walker%text) end select diff --git a/render.f90 b/render.f90 index 2913507..6d19729 100644 --- a/render.f90 +++ b/render.f90 @@ -11,6 +11,7 @@ implicit none procedure::render_proportional procedure(initialize), deferred::initialize + procedure(prepare_for_layout), deferred::prepare_for_layout procedure(calculate_width), deferred::text_width procedure(calculate_height), deferred::text_height @@ -21,6 +22,11 @@ implicit none procedure(calculate_height), deferred::preformatted_height procedure(calculate_visibility), deferred::is_preformatted_visible procedure(draw_text), deferred::draw_preformatted + + procedure(calculate_width), deferred::link_width + procedure(calculate_height), deferred::link_height + procedure(calculate_visibility), deferred::is_link_visible + procedure(draw_link), deferred::draw_link end type renderer @@ -31,6 +37,13 @@ implicit none end subroutine initialize end interface + abstract interface + subroutine prepare_for_layout(self) + import::renderer + class(renderer)::self + end subroutine prepare_for_layout + end interface + abstract interface function calculate_width(self, text) import::renderer @@ -65,6 +78,14 @@ implicit none logical::calculate_visibility end function calculate_visibility end interface + + abstract interface + subroutine draw_link(self, text, url) + import::renderer + class(renderer)::self + character(*), intent(in)::text, url + end subroutine draw_link + end interface contains @@ -170,4 +191,47 @@ contains r%y = r%y + r%preformatted_height(text) end subroutine render_preformatted + + subroutine render_link(r, text) + implicit none + + class(renderer)::r + character(*)::text + integer::i_whitespace, d_length + + character(len=:), allocatable::url, display + + ! Find the url first - just allocate the same + ! size as the text, good enough... + allocate(character(len=len_trim(text)) :: url) + url = adjustl(text) + + ! The display text occurs after the first whitespace + ! in url now + i_whitespace = index(trim(url)," ") + if(index(trim(url), CHAR(9)) > 0) then + if(i_whitespace == 0 .OR. index(trim(url), CHAR(9)) < i_whitespace) then + i_whitespace = index(trim(url), CHAR(9)) + end if + end if + + if(i_whitespace == 0) then + allocate(character(len=len_trim(url)) :: display) + display = url + else + d_length = len_trim(url) - i_whitespace + 1 + allocate(character(len=d_length) :: display) + display = adjustl(url(i_whitespace:len_trim(url))) + end if + + if(r%is_link_visible(display)) then + call r%draw_link(display, url) + end if + r%y = r%y + r%link_height(display) + + deallocate(url) + deallocate(display) + + end subroutine render_link + end module render diff --git a/samples/sample1.gmi b/samples/sample1.gmi index a7de966..a9e14b7 100644 --- a/samples/sample1.gmi +++ b/samples/sample1.gmi @@ -8,6 +8,9 @@ This page is actual a simple sample of a gemini text file. Tada! ``` +=> gemini://google.com Google Search Engine +=> gemini://bing.com + Margaux sat alone on the old stone wall running along the dirt road in front of her house. The sun still shined brightly in the late afternoon, and she relished its warmth. As summer was slowly waning, these days would be rarer still. Reaching into a bowl, she absently threw bread chunks to the six large geese that stared at her expectantly from the road's birm. Looking eastward along the road and adjoining plains and farmlands, she hoped to see a man approach on foot. Henry was due back shortly. -- cgit v1.2.3