%D \module %D [ file=mp-cell.mpiv, % mp-step.mpiv, %D version=2010.10.07, % 2001.05.22, %D title=\CONTEXT\ \METAPOST\ graphics, %D subtitle=steps, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA / Hans Hagen \& Ton Otten}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See licen-en.pdf for %C details. % step prefixes .. no save needed if known context_cell : endinput ; fi ; boolean context_cell ; context_cell := true ; def initialize_step_variables = save text_fill_color, text_line_color, text_line_width, text_offset, cell_fill_color, cell_line_color, cell_line_width, cell_offset, line_line_color, line_line_width, line_alternative, line_distance, cell_distance_y, cell_distance_x, nofcells, chart_vertical ; color text_line_color ; text_line_color := red ; color cell_line_color ; cell_line_color := blue ; color line_line_color ; line_line_color := green ; color text_fill_color ; text_fill_color := white ; color cell_fill_color ; cell_fill_color := white ; numeric text_line_width ; text_line_width := 2pt ; numeric cell_line_width ; cell_line_width := 2pt ; numeric line_line_width ; line_line_width := 2pt ; numeric text_offset ; text_offset := 4pt ; numeric cell_offset ; cell_offset := 4pt ; numeric line_distance ; line_distance := 10pt ; % between line and text numeric line_offset ; line_offset := 4pt ; % between center and start of line numeric line_height ; line_height := 20pt ; numeric cell_distance_y ; cell_distance_y := 20pt ; numeric cell_distance_x ; cell_distance_x := 20pt ; numeric text_distance_set ; text_distance_set := 4pt ; boolean chart_vertical ; chart_vertical := false ; numeric nofcells ; nofcells := 0 ; enddef ; def step_cells (expr t, b) = nofcells := nofcells + 1 ; cells_t[nofcells] := textext.d(t) ; cells_b[nofcells] := textext.d(b) ; texts_t[nofcells] := nullpicture ; texts_m[nofcells] := nullpicture ; texts_b[nofcells] := nullpicture ; enddef ; def step_texts (expr t, b) = texts_t[nofcells] := textext.d(t) ; texts_m[nofcells] := textext.d(m) ; texts_b[nofcells] := textext.d(b) ; enddef ; def step_begin_cell = nofcells := nofcells + 1 ; cells_t[nofcells] := nullpicture ; cells_b[nofcells] := nullpicture ; texts_t[nofcells] := nullpicture ; texts_m[nofcells] := nullpicture ; texts_b[nofcells] := nullpicture ; enddef ; def step_end_cell = enddef ; def step_cell_top (expr t) = cells_t[nofcells] := textext.d(t) ; enddef ; def step_cell_bot (expr b) = cells_b[nofcells] := textext.d(b) ; enddef ; def step_text_top (expr t) = texts_t[nofcells] := textext.d(t) ; enddef ; def step_text_mid (expr m) = texts_m[nofcells] := textext.d(m) ; enddef ; def step_text_bot (expr b) = texts_b[nofcells] := textext.d(b) ; enddef ; def step_begin_chart = begingroup ; initialize_step_variables ; save nofcells ; numeric nofcells ; nofcells := 0 ; save cells_t, cells_m, cells_b ; picture cells_t[], cells_m[], cells_b[] ; save texts_t, texts_m, texts_b ; picture texts_t[], texts_m[], texts_b[] ; enddef ; def step_end_chart = % we could combine some loops but this is cleaner save dx, delta ; numeric dx, delta ; save p ; path p ; save one_row_only ; boolean one_row_only ; save cell_t, next_t, text_t ; picture cell_t, next_t, text_t ; save cell_m, next_m, text_m ; picture cell_m, next_m, text_m ; save cell_b, next_b, text_b ; picture cell_b, next_b, text_b ; save height_t, width_t, max_height_t, max_width_t ; numeric height_t, width_t, max_height_t, max_width_t ; save height_m, width_m, max_height_m, max_width_m ; numeric height_m, width_m, max_height_m, max_width_m ; save height_b, width_b, max_height_b, max_width_b ; numeric height_b, width_b, max_height_b, max_width_b ; % check rows one_row_only := true ; for i=1 upto nofcells : if bbwidth(cells_b[i]) > 0 : one_row_only := false ; fi ; endfor ; % swap and rotate if chart_vertical : if one_row_only : % deal with mid_texts max_width_t := max_width_m := max_width_b := 0 ; for i=1 upto nofcells : width_t := bbwidth(texts_t[i]) ; width_m := bbwidth(texts_m[i]) ; width_b := bbwidth(texts_b[i]) ; if width_t > max_width_t : max_width_t := width_t fi ; if width_m > max_width_m : max_width_m := width_m fi ; if width_b > max_width_b : max_width_b := width_b fi ; endfor ; if max_width_m > 0 : for i=1 upto nofcells : text_t := texts_t[i] ; width_t := bbwidth(text_t) ; text_m := texts_m[i] ; width_m := bbwidth(text_m) ; text_b := texts_b[i] ; width_b := bbwidth(text_b) ; if width_t < max_width_t : setbounds text_t to boundingbox text_t leftenlarged (max_width_t - width_t) ; fi ; if width_m < max_width_m : setbounds text_m to boundingbox text_m leftenlarged ((max_width_m - width_m)/2) ; setbounds text_m to boundingbox text_m rightenlarged ((max_width_m - width_m)/2) ; fi ; if width_b < max_width_b : setbounds text_b to boundingbox text_b rightenlarged (max_width_b - width_b) ; fi ; text_t := text_t shifted (- xpart llcorner text_t, 0) ; text_m := text_m shifted (- xpart llcorner text_m, 0) ; text_b := text_b shifted (- xpart llcorner text_b, 0) ; texts_t[i] := image ( draw text_t ; draw text_m shifted (max_width_t + text_distance_set,0) ; draw text_b shifted (max_width_t + max_width_m + 2*text_distance_set,0) ; ) rotated 90 ; texts_m[i] := texts_b[i] := nullpicture ; cells_t[i] := cells_t[i] rotated 90 ; endfor ; else : for i=1 upto nofcells : cells_t[i] := cells_t[i] rotated 90 ; texts_t[i] := texts_t[i] rotated 90 ; texts_b[i] := texts_b[i] rotated 90 ; endfor ; fi ; else : for i=1 upto nofcells : cell_t := cells_t[i] ; cell_b := cells_b[i] ; cells_t[i] := cell_b rotated 90 ; cells_b[i] := cell_t rotated 90 ; text_t := texts_t[i] ; text_b := texts_b[i] ; texts_t[i] := text_b rotated 90 ; texts_b[i] := text_t rotated 90 ; endfor ; fi ; fi ; % align horizontal for i=1 upto nofcells : cell_t := cells_t[i] ; cell_b := cells_b[i] ; width_t := bbwidth(cell_t) ; width_b := bbwidth(cell_b) ; if (width_t = 0) and (width_b = 0) : % skip elseif (width_t > 0) and (width_t < width_b) : delta := (width_b-width_t)/2 ; setbounds cell_t to boundingbox cell_t leftenlarged delta rightenlarged delta ; cells_t[i] := cell_t ; elseif (width_b > 0) and (width_t > width_b) : delta := (width_t-width_b)/2 ; setbounds cell_b to boundingbox cell_b leftenlarged delta rightenlarged delta ; cells_b[i] := cell_b ; fi ; endfor ; % analyze vertical max_height_t := 0 ; max_height_b := 0 ; for i=1 upto nofcells : cell_t := cells_t[i] ; cell_b := cells_b[i] ; height_t := bbheight(cell_t) ; height_b := bbheight(cell_b) ; if height_t > 0 : setbounds cell_t to boundingbox cell_t enlarged cell_offset ; height_t := height_t + 2 * cell_offset ; cells_t[i] := cell_t ; fi ; if height_b > 0 : setbounds cell_b to boundingbox cell_b enlarged cell_offset ; height_b := height_b + 2 * cell_offset ; cells_b[i] := cell_b ; fi ; if height_t > max_height_t : max_height_t := height_t ; fi if height_b > max_height_b : max_height_b := height_b ; fi ; endfor ; % align vertical for i=1 upto nofcells : cell_t := cells_t[i] ; cell_b := cells_b[i] ; height_t := bbheight(cell_t) ; height_b := bbheight(cell_b) ; if height_t > 0 : delta := (max_height_t-height_t)/2 ; setbounds cell_t to boundingbox cell_t topenlarged delta bottomenlarged delta ; fi ; if height_b > 0 : delta := (max_height_b-height_b)/2 ; setbounds cell_b to boundingbox cell_b topenlarged delta bottomenlarged delta ; fi ; cells_t[i] := cell_t ; cells_b[i] := cell_b ; endfor ; % position dx := 0 ; for i=1 upto nofcells : cell_t := cells_t[i] ; cell_b := cells_b[i] ; cell_t := cell_t shifted -llcorner cell_t ; cell_b := cell_b shifted -llcorner cell_b ; cell_t := cell_t shifted (dx, 0) ; cell_b := cell_b shifted (dx,-cell_distance_y-max_height_b) ; cells_t[i] := cell_t ; cells_b[i] := cell_b ; width_t := bbwidth(cell_t) ; width_b := bbwidth(cell_b) ; if width_t > 0 : dx := dx + cell_distance_x + width_t ; elseif width_b > 0 : dx := dx + cell_distance_x + width_b ; fi ; endfor ; % flush for i=1 upto nofcells : cell_t := cells_t[i] ; cell_b := cells_b[i] ; width_t := bbwidth(cell_t) ; width_b := bbwidth(cell_b) ; if width_t > 0 : fill boundingbox cell_t withcolor cell_fill_color ; draw boundingbox cell_t withpen pencircle scaled cell_line_width withcolor cell_line_color ; draw cell_t ; fi ; if width_b > 0 : fill boundingbox cell_b withcolor cell_fill_color ; draw boundingbox cell_b withpen pencircle scaled cell_line_width withcolor cell_line_color ; draw cell_b ; fi ; endfor ; % def midtopboundary expr p = 0.5[ulcorner boundingbox p, urcorner boundingbox p] enddef ; def midbottomboundary expr p = 0.5[llcorner boundingbox p, lrcorner boundingbox p] enddef ; % draw top and bottom text boxes for i=1 upto nofcells-1 : text_t := texts_t[i] ; text_b := texts_b[i] ; if bbwidth(text_t) > 0 : setbounds text_t to boundingbox text_t enlarged text_offset ; texts_t[i] := text_t ; fi ; if bbwidth(text_b) > 0 : setbounds text_b to boundingbox text_b enlarged text_offset ; texts_b[i] := text_b ; fi ; endfor ; % arrows for i=1 upto nofcells-1 : cell_t := cells_t[i] ; cell_b := cells_b[i] ; next_t := cells_t[i+1] ; next_b := cells_b[i+1] ; pair t_a, t_b, t_c, b_a, b_b, b_c ; t_a := midtopboundary cell_t ; t_b := midtopboundary next_t ; t_c := (xpart 0.5[t_a,t_b], ypart t_a+line_height+line_distance) ; if one_row_only : b_a := midbottomboundary cell_t ; b_b := midbottomboundary next_t ; else : b_a := midbottomboundary cell_b ; b_b := midbottomboundary next_b ; fi ; b_c := (xpart 0.5[b_a,b_b], ypart b_a-line_height-line_distance) ; texts_t[i] := thelabel.top(texts_t[i],t_c) ; texts_b[i] := thelabel.bot(texts_b[i],b_c) ; endfor ; % for i=1 upto nofcells-1 : % todo arrows when empty text cell_t := cells_t[i] ; cell_b := cells_b[i] ; next_t := cells_t[i+1] ; next_b := cells_b[i+1] ; text_t := texts_t[i] ; text_b := texts_b[i] ; if bbwidth(text_t) > 0 : if bbwidth(cell_t) > 0 : drawarrow midtopboundary cell_t shifted (if i > 1 : line_offset else : 0 fi, cell_line_width) {up} .. midbottomboundary text_t shifted (0,-line_distance) .. {down} midtopboundary next_t shifted(if i < nofcells - 1 : -line_offset else : 0 fi,cell_line_width) withpen pencircle scaled line_line_width withcolor line_line_color ; else : fi ; fi ; if bbwidth(text_b) > 0 : if one_row_only : cell_b := cell_t ; next_b := next_t ; fi ; if bbwidth(cell_b) > 0 : drawarrow midbottomboundary cell_b shifted (if i > 1 : line_offset else : 0 fi, -cell_line_width) {down} .. midtopboundary text_b shifted (0, line_distance) .. {up} midbottomboundary next_b shifted (if i < nofcells - 1 : -line_offset else : 0 fi,-cell_line_width) withpen pencircle scaled line_line_width withcolor line_line_color ; else : fi ; fi ; endfor ; % draw top and bottom text boxes for i=1 upto nofcells-1 : text_t := texts_t[i] ; text_b := texts_b[i] ; if bbwidth(text_t) > 0 : fill boundingbox text_t withcolor text_fill_color ; draw boundingbox text_t withpen pencircle scaled text_line_width withcolor text_line_color ; draw text_t ; fi ; if bbwidth(text_b) > 0 : fill boundingbox text_b withcolor text_fill_color ; draw boundingbox text_b withpen pencircle scaled text_line_width withcolor text_line_color ; draw text_b ; fi ; endfor ; if chart_vertical : % rotate back currentpicture := currentpicture rotated -90 ; fi ; endgroup ; enddef ; % start_begin_step ; % step_cells ("\strut test 0", "\strut test 0") ; % step_cells ("\strut test 1", "\vbox{\hsize3cm \strut oeps 1\crlf oeps 1}") ; % step_texts ("\strut 1", "\strut 1") ; % step_cells ("\strut test 2", "\strut oeps 2 oeps 2") ; % step_cells ("\strut test X", "\strut test X") ; % step_texts ("\strut 2", "\strut 2") ; % step_cells ("\strut test 3", "\strut oeps 3 oeps 3") ; % step_texts ("\strut 3", "\strut 3") ; % step_cells ("\strut test 4", "\strut oeps 4 oeps 4") ; % step_texts ("\strut 4", "\strut 4") ; % stop_end_chart ;