@@ -2737,10 +2737,10 @@ =head2 Macros for displaying images
27372737
27382738Usage :
27392739
2740- image($image , width => 200 , height => 200 , tex_size => 800 , valign => 'middle' , alt => 'alt text' , extra_html_tags => 'style="border:solid black 1pt"' );
2740+ image($image , width => . .. , height => ... , tex_size => ... , valign => ... , alt => ..., long_description => ... );
27412741
27422742where C <$image > can be a local file path , URL , WWPlot object , PGlateximage object ,
2743- PGtikz object , or parser ::GraphTool object .
2743+ PGtikz object , Plots :: Plot object , or parser ::GraphTool object .
27442744
27452745C <width > and C <height > are positive integer pixel counts for HTML display . If both
27462746are missing , C <width > will default to 200 and C <height > will remain undeclared ,
@@ -2757,10 +2757,34 @@ =head2 Macros for displaying images
27572757C <valign > can be 'top' , 'middle' , or 'bottom' . This aligns the image relative to
27582758the surrounding line of text .
27592759
2760- image ([$image1 ,$image2 ], width => 200 , height => 200 , tex_size => 800 , alt => ['alt text 1' ,'alt text 2' ], extra_html_tags => 'style="border:solid black 1pt"' );
2761- image([$image1 ,$image2 ], width => 200 , height => 200 , tex_size => 800 , alt => 'common alt text' , extra_html_tags => 'style="border:solid black 1pt"' );
2760+ C <alt > should be a string , ideally with fewer than 125 characters , that describes the
2761+ most important features of the image . This should always be used. If the image is
2762+ decorative , C << alt => '' >> should be used .
27622763
2763- this produces an array in array context and joins the elements with C <' ' > in scalar context
2764+ C <long_description > provides an optional way to give a more complete description of
2765+ an image . This may include a table (for example to describe complex data in a graph).
2766+ It may be helpful to generate blocks of text and tables and store them in a variable ,
2767+ and pass that variable to C <long_description >.
2768+
2769+ C <long_description_width > defaults to 1 . This should be a positive number at most 1.
2770+ In hardcopy output , this portion of the line width will be used to cap the width
2771+ of the long description (if there is one ). This is useful for example when the image
2772+ is inside a table .
2773+
2774+ C <extra_html_tags > [DEPRECATED ] can be a string will directly be placed into the
2775+ HTML img element . For example, C<< extra_html_tags => 'style="border:solid black 1pt"' >>.
2776+
2777+ The first argument to C <image()> can alternatively be an array of images :
2778+
2779+ image([$image1 , $image2 ], . ..);
2780+
2781+ If so then if C <alt > or C <long_description > are not arrays , they will be used
2782+ repeatedly for each image . Each of C<alt> and C<long_description> can instead be
2783+ arrays of the same length and their entries will be used with the corresponding
2784+ image .
2785+
2786+ In array context , using C <image()> this way will produces an array in array context
2787+ and join the elements with C <' ' > in scalar context .
27642788
27652789=cut
27662790
@@ -2778,8 +2802,10 @@ sub image {
27782802 tex_size => '' ,
27792803 valign => 'middle' ,
27802804 # default value for alt is undef , since an empty string is the explicit indicator of a decorative image
2781- alt => undef ,
2782- extra_html_tags => '' ,
2805+ alt => undef ,
2806+ long_description => undef ,
2807+ long_description_width => 1 ,
2808+ extra_html_tags => '' ,
27832809 );
27842810 # handle options
27852811 my %out_options = %known_options ;
@@ -2802,9 +2828,12 @@ sub image {
28022828 $tex_size = 1000 if $tex_size > 1000 ;
28032829
28042830 my $alt = $out_options {alt };
2805- my $width_ratio = $tex_size * (.001 );
2831+ my $desc = $out_options {long_description };
2832+ my $ldw = $out_options {long_description_width };
2833+ my $width_ratio = $tex_size * 0 .001 ;
28062834 my @image_list = ();
28072835 my @alt_list = ();
2836+ my @desc_list = ();
28082837 my $valign = 'middle' ;
28092838 $valign = 'top' if ($out_options {valign } eq 'top' );
28102839 $valign = 'bottom' if ($out_options {valign } eq 'bottom' );
@@ -2823,16 +2852,58 @@ sub image {
28232852 } else {
28242853 for my $i (@image_list ) { push(@alt_list , $alt ) }
28252854 }
2855+ if (ref($desc ) =~ /ARRAY /) {
2856+ @desc_list = @{$desc };
2857+ } else {
2858+ for my $i (@image_list ) { push(@desc_list , $desc ) }
2859+ }
28262860
28272861 my @output_list = ();
28282862 while (@image_list ) {
2829- my $image_item = shift @image_list ;
2863+ my $image_item = shift @image_list ;
2864+ my $description_details = $desc ? shift(@desc_list ) : '' ;
2865+ if ($desc && $displayMode ne 'PTX' && $displayMode ne 'TeX' ) {
2866+ $description_details = tag(
2867+ 'details' ,
2868+ 'aria-live' => 'polite' ,
2869+ class => 'image-details' ,
2870+ name => 'image-details' ,
2871+ tag(
2872+ 'summary' ,
2873+ class => 'mt-1' ,
2874+ title => 'details' ,
2875+ tag(
2876+ 'span' ,
2877+ class => 'image-details-btn btn btn-sm btn-secondary fw-bold' ,
2878+ 'aria-hidden' => 'true' ,
2879+ maketext('image description' )
2880+ )
2881+ )
2882+ . tag(
2883+ 'div',
2884+ id => 'LONG-DESCRIPTION-ID' ,
2885+ class => 'image-details-content bg-white py-2 px-3 my-2 border' ,
2886+ $description_details
2887+ . tag(
2888+ 'div',
2889+ class => 'd-flex justify-content-end mt-2' ,
2890+ tag(
2891+ 'button' ,
2892+ class => 'image-details-dismiss btn btn-sm btn-secondary' ,
2893+ type => 'button' ,
2894+ maketext('Close image description' )
2895+ )
2896+ )
2897+ )
2898+ );
2899+ }
28302900 if (ref $image_item eq 'parser::GraphTool' ) {
28312901 push(
28322902 @output_list ,
28332903 $image_item ->generateAnswerGraph(
2834- $out_options {width } || $out_options {height } ? (width => $width , height => $height ) : (),
2835- $out_options {tex_size } || $out_options {width } ? (texSize => $tex_size ) : (),
2904+ $out_options {width } || $out_options {height } ? (width => $width , height => $height ) : (),
2905+ $out_options {tex_size } || $out_options {width } ? (texSize => $tex_size ) : (),
2906+ $desc ? (longDescription => $description_details ) : (),
28362907 ariaDescription => shift @alt_list // ''
28372908 )
28382909 );
@@ -2846,6 +2917,7 @@ sub image {
28462917 $image_item->axes->style(aria_description => shift @alt_list) if $out_options{alt};
28472918
28482919 if ($image_item ->ext eq 'html' ) {
2920+ $image_item ->{description_details } = $description_details ;
28492921 push(@output_list , $image_item ->draw );
28502922 next ;
28512923 }
@@ -2862,25 +2934,36 @@ sub image {
28622934 || ref $image_item eq 'PGtikz' );
28632935 my $imageURL = alias($image_item ) // '' ;
28642936 $imageURL = ($envir {use_site_prefix }) ? $envir {use_site_prefix } . $imageURL : $imageURL;
2865- my $out = "" ;
2937+ my $id = $main ::PG ->getUniqueName('img' );
2938+ my $out = '' ;
28662939
28672940 if ($displayMode eq 'TeX' ) {
28682941 my $imagePath = $imageURL ; # in TeX mode , alias gives us a path , not a URL
28692942
28702943 # We 're going to create PDF files with our TeX (using LaTeX ), so
28712944 # alias should have given us the path to a PNG image .
28722945 if ($imagePath ) {
2946+ if ($desc ) {
2947+ $out . = "\\parbox{$ldw\\linewidth}{";
2948+ $width_ratio = $width_ratio / $ldw;
2949+ }
28732950 if ($valign eq 'top' ) {
2874- $out = '\settoheight{\strutheight}{\strut}'
2875- . "\\raisebox{-\\height + \\strutheight} {\\includegraphics[width=$width_ratio\\linewidth]{$imagePath}}\n";
2951+ $out . = '\settoheight{\strutheight}{\strut}\raisebox{-\height + \strutheight }'
2952+ . "{\\includegraphics[width=$width_ratio\\linewidth]{$imagePath}}\n";
28762953 } elsif ($valign eq 'bottom') {
2877- $out = "\\includegraphics[width=$width_ratio\\linewidth]{$imagePath}\n";
2954+ $out . = "\\includegraphics[width=$width_ratio\\linewidth]{$imagePath}\n";
28782955 } else {
2879- $out = '\settoheight{\strutheight}{\strut}'
2880- . "\\raisebox{-0.5\\height + 0.5\\strutheight}{\\includegraphics[width=$width_ratio\\linewidth]{$imagePath}}\n";
2956+ $out .= '\settoheight{\strutheight}{\strut}\raisebox{-0.5\height + 0.5\strutheight}'
2957+ . "{\\includegraphics[width=$width_ratio\\linewidth]{$imagePath}}\n";
2958+ }
2959+ if ($desc ) {
2960+ $out . =
2961+ "\\newline\\par\\parbox{\\linewidth}{{\\scshape\\underline{"
2962+ . maketext('image description')
2963+ . "}}\\newline{}$description_details\\par\\hfill\\(\\overline{\\mbox{\\scshape "
2964+ . maketext('end image description')
2965+ . "}}\\)}}\\par\n";
28812966 }
2882- } else {
2883- $out = "";
28842967 }
28852968 } elsif ($displayMode eq 'HTML_MathJax'
28862969 || $displayMode eq 'HTML_dpng'
@@ -2889,15 +2972,31 @@ sub image {
28892972 {
28902973 my $altattrib = '' ;
28912974 if (defined $alt_list [0 ]) { $altattrib = 'alt="' . encode_pg_and_html(shift @alt_list) . '"' }
2892- $out =
2893- qq !<IMG SRC ="$imageURL" class ="image-view-elt $valign" tabindex ="0" role ="button" $width_attrib $height_attrib $out_options {extra_html_tags } $altattrib >!;
2975+ if ($desc ) {
2976+ $out . = tag(
2977+ 'div',
2978+ class => 'image-container pb-2' ,
2979+ qq !<img src ="$imageURL" class ="image-view-elt $valign" tabindex ="0" role ="button" !
2980+ . qq!$width_attrib$height_attrib aria-details="${id}_details" $out_options{extra_html_tags} $altattrib>!
2981+ . ($description_details =~ s/LONG-DESCRIPTION-ID/${id}_details/r)
2982+ );
2983+ } else {
2984+ $out .= qq!<img src="$imageURL" class="image-view-elt $valign" tabindex="0" role="button"!
2985+ . qq!$width_attrib$height_attrib $out_options{extra_html_tags} $altattrib>!;
2986+ }
28942987 } elsif ($displayMode eq 'PTX') {
28952988 my $ptxwidth = ($width ? int($width / 6 ) : 80 );
2989+ $out = qq !<image width ="$ptxwidth%" source ="$imageURL" >!;
28962990 if (defined $alt ) {
2897- $out = qq !<image width ="$ptxwidth%" source ="$imageURL" ><description >$alt </description ></image >!;
2898- } else {
2899- $out = qq !<image width ="$ptxwidth%" source ="$imageURL" />!;
2991+ $out . = "\n<shortdescription>$alt</shortdescription>";
2992+ }
2993+ if (defined $desc ) {
2994+ $out . = "\n<description>\n" . PTX_cleanup($description_details) . "\n</description>";
2995+ }
2996+ if (defined $alt || defined $desc ) {
2997+ $out . = "\n";
29002998 }
2999+ $out .= '</image>';
29013000 } else {
29023001 $out = "Error: PGbasicmacros: image: Unknown displayMode: $displayMode.\n";
29033002 }
0 commit comments