aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ag_render.f90103
-rw-r--r--dumb_render.f9043
-rw-r--r--render.f90155
3 files changed, 158 insertions, 143 deletions
diff --git a/ag_render.f90 b/ag_render.f90
index e98d7b6..fc80295 100644
--- a/ag_render.f90
+++ b/ag_render.f90
@@ -94,7 +94,7 @@ implicit none
procedure :: text_height => ag_text_height
procedure :: is_text_visible => ag_text_visible
- procedure :: draw_porportional => ag_text_draw
+ procedure :: draw_proportional => ag_text_draw
procedure :: preformatted_width => ag_preformatted_width
procedure :: preformatted_height => ag_preformatted_height
@@ -440,36 +440,46 @@ contains
end subroutine ag_new_page
- pure function get_font_size(self, heading)
+ pure function get_font_size(self, text_type)
implicit none
class(appgraphics_renderer), intent(in)::self
- integer, intent(in)::heading
+ integer, intent(in)::text_type
integer::get_font_size
get_font_size = self%font_size
- if(heading == 1) then
+ if(text_type == proportional_type_heading_1) then
get_font_size = 2*get_font_size
- else if(heading > 1) then
+ else if(text_type > proportional_type_heading_1) then
get_font_size = (3*get_font_size)/2
end if
end function get_font_size
- function ag_text_width(self, text, heading, list_item)
+ pure function get_indent_margin(self)
+ implicit none
+
+ type(appgraphics_renderer), intent(in)::self
+ integer::get_indent_margin
+
+ get_indent_margin = self%font_size + 2*self%bullet_margin
+
+ end function get_indent_margin
+
+ function ag_text_width(self, text, text_type)
use appgraphics
+ use render
implicit none
class(appgraphics_renderer)::self
character(*), intent(in)::text
- integer, intent(in), optional::heading
- logical, intent(in), optional::list_item
+ integer, intent(in), optional::text_type
integer::ag_text_width
integer::font_size
font_size = self%font_size
- if(present(heading)) then
- font_size = get_font_size(self, heading)
+ if(present(text_type)) then
+ font_size = get_font_size(self, text_type)
end if
call settextstyle(self%default_font, HORIZ_DIR, font_size)
@@ -481,28 +491,29 @@ contains
ag_text_width = ag_text_width + self%left_border + self%right_border
- if(present(list_item)) then
- if(list_item) then
- ag_text_width = ag_text_width + self%font_size/2 + 2*self%bullet_margin
+ if(present(text_type)) then
+ if(text_type == proportional_type_list_item) then
+ ag_text_width = ag_text_width + get_indent_margin(self)
+ else if(text_type == proportional_type_quotation) then
+ ag_text_width = ag_text_width + 2 * get_indent_margin(self)
end if
end if
end function ag_text_width
- function ag_text_height(self, text, heading, list_item)
+ function ag_text_height(self, text, text_type)
use appgraphics
implicit none
class(appgraphics_renderer)::self
character(*), intent(in)::text
- integer, intent(in), optional::heading
- logical, intent(in), optional::list_item
+ integer, intent(in), optional::text_type
integer::ag_text_height
integer::font_size
font_size = self%font_size
- if(present(heading)) then
- font_size = get_font_size(self, heading)
+ if(present(text_type)) then
+ font_size = get_font_size(self, text_type)
end if
call settextstyle(self%default_font, HORIZ_DIR, font_size)
@@ -526,43 +537,55 @@ contains
end function ag_text_visible
- subroutine ag_text_draw(self, text, heading, list_item)
+ subroutine ag_text_draw(self, text, text_type)
use appgraphics
implicit none
class(appgraphics_renderer)::self
character(*), intent(in)::text
- integer, intent(in), optional::heading
- logical, intent(in), optional::list_item
+ integer, intent(in), optional::text_type
integer::font_size
integer::x, bx, by
+ integer::font_color
font_size = self%font_size
- if(present(heading)) then
- font_size = get_font_size(self, heading)
-
- ! The first level 1 heading can be guessed as the page title
- if(heading == 1 .and. .not. self%title_guessed) then
- call set_window_title(self, text)
- self%title_guessed = .true.
- end if
- end if
-
+ font_color = self%text_color
x = self%left_border
- if(present(list_item)) then
- if(list_item) then
- bx = x + self%bullet_margin
- by = self%y + self%font_size/4
+
+ if(present(text_type)) then
+ font_size = get_font_size(self, text_type)
+
+ select case(text_type)
- call setfillstyle(SOLID_FILL, self%text_color)
- call bar(bx, by, bx+self%font_size/2, by+self%font_size/2)
+ case (proportional_type_heading_1)
+ ! The first level 1 heading can be guessed as the page title
+ if(.not. self%title_guessed) then
+
+ call set_window_title(self, text)
+ self%title_guessed = .true.
- x = bx + self%bullet_margin + self%font_size/2
- end if
+ end if
+
+ case (proportional_type_list_item)
+ ! If a list item, need to draw a box
+ bx = x + self%bullet_margin
+ by = self%y + self%font_size/4
+
+ call setfillstyle(SOLID_FILL, self%text_color)
+ call bar(bx, by, bx+self%font_size/2, by+self%font_size/2)
+
+ x = get_indent_margin(self)
+
+ case (proportional_type_quotation)
+ ! Scoot in and draw grey
+ x = x + get_indent_margin(self)
+ font_color = DARKGRAY
+
+ end select
end if
call settextstyle(self%default_font, HORIZ_DIR, font_size)
- call setcolor(self%text_color)
+ call setcolor(font_color)
call outtextxy(x, self%y, trim(text))
end subroutine ag_text_draw
diff --git a/dumb_render.f90 b/dumb_render.f90
index 23b991b..be911b7 100644
--- a/dumb_render.f90
+++ b/dumb_render.f90
@@ -29,6 +29,8 @@ implicit none
character, parameter::bullet_character = '-'
+ integer, parameter::indent_margin = 3
+
type, extends(renderer) :: dumb_renderer
integer::link_index
@@ -46,7 +48,7 @@ implicit none
procedure :: text_height => dumb_text_height
procedure :: is_text_visible => dumb_text_visible
- procedure :: draw_porportional => dumb_text_draw
+ procedure :: draw_proportional => dumb_text_draw
procedure :: preformatted_width => dumb_simple_width
procedure :: preformatted_height => dumb_simple_height
@@ -127,38 +129,38 @@ contains
end function store_link
- function dumb_text_width(self, text, heading, list_item)
+ function dumb_text_width(self, text, text_type)
implicit none
class(dumb_renderer)::self
character(*), intent(in)::text
- integer, intent(in), optional::heading
- logical, intent(in), optional::list_item
+ integer, intent(in), optional::text_type
integer::dumb_text_width
dumb_text_width = len_trim(text)
- if(present(list_item)) then
- if(list_item) then
- dumb_text_width = dumb_text_width + 3
+ if(present(text_type)) then
+ if(text_type == proportional_type_list_item) then
+ dumb_text_width = dumb_text_width + indent_margin
+ else if(text_type == proportional_type_quotation) then
+ dumb_text_width = dumb_text_width + 2*indent_margin
end if
end if
end function dumb_text_width
- function dumb_text_height(self, text, heading, list_item)
+ function dumb_text_height(self, text, text_type)
implicit none
class(dumb_renderer)::self
character(*), intent(in)::text
- integer, intent(in), optional::heading
- logical, intent(in), optional::list_item
+ integer, intent(in), optional::text_type
integer::dumb_text_height
dumb_text_height = 1
- if(present(heading)) then
- if(heading > 0) then
+ if(present(text_type)) then
+ if(text_type > 0) then
dumb_text_height = 2
end if
end if
@@ -222,21 +224,22 @@ contains
end if
end subroutine dumb_simple_draw
- subroutine dumb_text_draw(self, text, heading, list_item)
+ subroutine dumb_text_draw(self, text, text_type)
implicit none
class(dumb_renderer)::self
character(*), intent(in)::text
- integer, intent(in), optional::heading
- logical, intent(in), optional::list_item
+ integer, intent(in), optional::text_type
integer::limit_x
character(5)::formatting
character(self%max_width)::heading_line
! Put a bullet for list items
- if(present(list_item)) then
- if(list_item) then
+ if(present(text_type)) then
+ if(text_type == proportional_type_list_item) then
write(*, '(1X, A1, 1X)', advance='no') bullet_character
+ else if(text_type == proportional_type_quotation) then
+ write(*, '(3X)', advance='no')
end if
end if
@@ -254,10 +257,10 @@ contains
end if
! For headings, plop a second line as an underline
- if(present(heading)) then
- if(heading > 0) then
+ if(present(text_type)) then
+ if(text_type > 0) then
if(limit_x > 0) then
- if(heading == 1) then
+ if(text_type == proportional_type_heading_1) then
heading_line = repeat("=", limit_x)
else
heading_line = repeat("-", limit_x)
diff --git a/render.f90 b/render.f90
index 335cbcb..b37eb50 100644
--- a/render.f90
+++ b/render.f90
@@ -32,6 +32,11 @@ implicit none
integer, parameter::last_break = -1
+ integer, parameter::proportional_type_normal = 0
+ integer, parameter::proportional_type_list_item = -1
+ integer, parameter::proportional_type_quotation = -2
+ integer, parameter::proportional_type_heading_1 = 1 ! For heading level, it's just positive
+
character(11), dimension(2)::base_supported_types = &
["text/plain ", &
"text/gemini" ]
@@ -57,7 +62,7 @@ implicit none
procedure(calculate_width), deferred::text_width
procedure(calculate_height), deferred::text_height
procedure(calculate_visibility), deferred::is_text_visible
- procedure(draw_text), deferred::draw_porportional
+ procedure(draw_text), deferred::draw_proportional
procedure(calculate_simple_width), deferred::preformatted_width
procedure(calculate_simple_height), deferred::preformatted_height
@@ -103,34 +108,31 @@ implicit none
end interface
abstract interface
- function calculate_width(self, text, heading, list_item)
+ function calculate_width(self, text, text_type)
import::renderer
class(renderer)::self
character(*), intent(in)::text
- integer, intent(in), optional::heading
- logical, intent(in), optional::list_item
+ integer, intent(in), optional::text_type
integer::calculate_width
end function calculate_width
end interface
abstract interface
- function calculate_height(self, text, heading, list_item)
+ function calculate_height(self, text, text_type)
import::renderer
class(renderer)::self
character(*), intent(in)::text
- integer, intent(in), optional::heading
- logical, intent(in), optional::list_item
+ integer, intent(in), optional::text_type
integer::calculate_height
end function calculate_height
end interface
abstract interface
- subroutine draw_text(self, text, heading, list_item)
+ subroutine draw_text(self, text, text_type)
import::renderer
class(renderer)::self
character(*), intent(in)::text
- integer, intent(in), optional::heading
- logical, intent(in), optional::list_item
+ integer, intent(in), optional::text_type
end subroutine draw_text
end interface
@@ -256,14 +258,13 @@ contains
end function report_unsupported_protocol
- function width_of_line(r, text, startpos, endpos, heading_level, list_item)
+ function width_of_line(r, text, startpos, endpos, proportional_type)
implicit none
class(renderer)::r
character(*), intent(in)::text
integer, intent(in)::startpos, endpos
- integer, intent(in)::heading_level
- logical, intent(in)::list_item
+ integer, intent(in)::proportional_type
integer::width_of_line
integer::my_start, my_end
@@ -282,20 +283,18 @@ contains
width_of_line = 0
else
width_of_line = r%text_width(text(my_start:my_end), &
- heading=heading_level, &
- list_item=list_item)
+ text_type=proportional_type)
end if
end function width_of_line
- function wrap_line(r, text, startpos, heading_level, list_item) result(endpos)
+ function wrap_line(r, text, startpos, proportional_type) result(endpos)
implicit none
class(renderer)::r
character(*), intent(in)::text
integer, intent(in)::startpos
- integer, intent(in)::heading_level
- logical, intent(in)::list_item
+ integer, intent(in)::proportional_type
integer::endpos
integer::my_start
integer::w
@@ -306,7 +305,7 @@ contains
end if
endpos = len_trim(text)
- w = width_of_line(r, text, my_start, endpos, heading_level, list_item)
+ w = width_of_line(r, text, my_start, endpos, proportional_type)
do while(w > r%max_width)
endpos = endpos - 1
@@ -314,11 +313,46 @@ contains
endpos = endpos - 1
end do
- w = width_of_line(r, text, my_start, endpos, heading_level, list_item)
+ w = width_of_line(r, text, my_start, endpos, proportional_type)
end do
end function wrap_line
+ function get_start_position_and_type(text, proportional_type) result(startpos)
+ implicit none
+
+ character(*), intent(in)::text
+ integer, intent(out)::proportional_type
+ integer::startpos
+
+ startpos = 1
+ proportional_type = proportional_type_normal
+
+ ! Check for headings first
+ do while(text(startpos:startpos) == '#')
+ proportional_type = proportional_type + 1
+ startpos = startpos + 1
+ end do
+
+ if(proportional_type == proportional_type_normal) then
+ if(text(1:1) == '*') then
+ proportional_type = proportional_type_list_item
+ startpos = startpos + 1
+ else if(text(1:1) == '>') then
+ proportional_type = proportional_type_quotation
+ startpos = startpos + 1
+ end if
+ end if
+
+ ! If either occurred, advance past whitespace
+ if(proportional_type /= proportional_type_normal) then
+ do while(text(startpos:startpos) == ' ' .or. text(startpos:startpos) == char(9))
+ startpos = startpos + 1
+ end do
+ end if
+
+ end function get_start_position_and_type
+
function calculate_wrapping(r, text) result(breaks)
implicit none
@@ -327,8 +361,8 @@ contains
integer, dimension(:), pointer::breaks
integer::startpos, endpos
- integer::heading_level
- logical::list_item
+ integer::proportional_type
+ logical::list_item, quotation
integer::current_allocation
integer::break_count
@@ -340,32 +374,9 @@ contains
if(len_trim(text) > 0) then
- startpos = 1
-
- ! Check for headings first
- heading_level = 0
- do while(text(startpos:startpos) == '#')
- heading_level = heading_level + 1
- startpos = startpos + 1
- end do
-
- ! Or a list item
- list_item = .FALSE.
- if(heading_level == 0) then
- list_item = (text(1:1) == '*')
- if(list_item) then
- startpos = startpos + 1
- end if
- end if
+ startpos = get_start_position_and_type(text, proportional_type)
- ! If either occurred, advance past whitespace
- if(heading_level > 0 .or. list_item) then
- do while(text(startpos:startpos) == ' ' .or. text(startpos:startpos) == char(9))
- startpos = startpos + 1
- end do
- end if
-
- endpos = wrap_line(r, text, startpos, heading_level, list_item)
+ endpos = wrap_line(r, text, startpos, proportional_type)
do while(endpos > startpos)
! Save this break
@@ -392,8 +403,11 @@ contains
end do
! Do not mark as a list item for subsequent lines
- list_item = .FALSE.
- endpos = wrap_line(r, text, startpos, heading_level, list_item)
+ if(proportional_type == proportional_type_list_item) then
+ proportional_type = proportional_type_normal
+ end if
+
+ endpos = wrap_line(r, text, startpos, proportional_type)
end do
end if
@@ -423,44 +437,19 @@ contains
integer, dimension(:)::breaks
integer::startpos, endpos
- integer::heading_level
- logical::list_item
-
+ integer::proportional_type
integer::break_index
if(len_trim(text) == 0) then
if(r%is_text_visible(" ")) then
- call r%draw_porportional("")
+ call r%draw_proportional("")
end if
r%y = r%y + r%text_height(" ")
else
- startpos = 1
-
- ! Check for headings first
- heading_level = 0
- do while(text(startpos:startpos) == '#')
- heading_level = heading_level + 1
- startpos = startpos + 1
- end do
-
- ! Or a list item
- list_item = .FALSE.
- if(heading_level == 0) then
- list_item = (text(1:1) == '*')
- if(list_item) then
- startpos = startpos + 1
- end if
- end if
-
- ! If either occurred, advance past whitespace
- if(heading_level > 0 .or. list_item) then
- do while(text(startpos:startpos) == ' ' .or. text(startpos:startpos) == char(9))
- startpos = startpos + 1
- end do
- end if
+ startpos = get_start_position_and_type(text, proportional_type)
break_index = 1
endpos = breaks(break_index)
@@ -470,13 +459,11 @@ contains
do while(endpos > startpos)
if(r%is_text_visible(text(startpos:endpos))) then
- call r%draw_porportional(text(startpos:endpos), &
- heading=heading_level, &
- list_item=list_item)
+ call r%draw_proportional(text(startpos:endpos), &
+ text_type=proportional_type)
end if
r%y = r%y + r%text_height(text(startpos:endpos), &
- heading=heading_level, &
- list_item=list_item)
+ text_type=proportional_type)
! Advance string positions
startpos = endpos+1
@@ -485,7 +472,9 @@ contains
end do
! Do not mark as a list item for subsequent lines
- list_item = .FALSE.
+ if(proportional_type == proportional_type_list_item) then
+ proportional_type = proportional_type_normal
+ end if
if(breaks(break_index) /= last_break) then
break_index = break_index + 1