class_docstr: default setting for report constants
docstr: add an block of images formatted with grid specification
  
  Args:
      image_set (dict or list):
          dict, indicate image paths
              - key: image_name
              - value: image_path
          or list, indicate image paths in sequence
  
      grid_spec (dict): indicate image size and position
          - key: image_name, or index if image_set is a list
          - value: (x,y,w,h) position and weight/height of image,
             with left top corner of the block as (0,0), unit in mm
  
      ratio (bool): indicate grid specification by ratio
          instead of absolute size.
          If True, grid_width and grid_height are required.
  
      grid_width (int): width of the entire grid block (unit in mm)
  
      grid_height (int): height of the entire grid block (unit in mm)
  
      caption (str): caption of the entire grid block
  
      style (str): style of caption
  Returns:
      (bool) True if image blocks generate successfully, otherwise False
docstr_tok: ["add","an","block","of","images","formatted","with","grid","specification","Args",":","image_set","(","dict","or","list",")",":","dict",",","indicate","image","paths","-","key",":","image_name","-","value",":","image_path","or","list",",","indicate","image","paths","in","sequence","grid_spec","(","dict",")",":","indicate","image","size","and","position","-","key",":","image_name",",","or","index","if","image_set","is","a","list","-","value",":","(","x",",","y",",","w",",","h",")","position","and","weight\/height","of","image",",","with","left","top","corner","of","the","block","as","(","0,0",")",",","unit","in","mm","ratio","(","bool",")",":","indicate","grid","specification","by","ratio","instead","of","absolute","size",".","If","True",",","grid_width","and","grid_height","are","required",".","grid_width","(","int",")",":","width","of","the","entire","grid","block","(","unit","in","mm",")","grid_height","(","int",")",":","height","of","the","entire","grid","block","(","unit","in","mm",")","caption","(","str",")",":","caption","of","the","entire","grid","block","style","(","str",")",":","style","of","caption","Returns",":","(","bool",")","True","if","image","blocks","generate","successfully",",","otherwise","False"]
code: def add_grid_images(
      self,
      image_set,
      grid_spec,
      ratio=False,
      grid_width=None,
      grid_height=None,
      caption=None,
      style=None,
  ):
      """
      add an block of images formatted with grid specification
  
      Args:
          image_set (dict or list):
              dict, indicate image paths
                  - key: image_name
                  - value: image_path
              or list, indicate image paths in sequence
  
          grid_spec (dict): indicate image size and position
              - key: image_name, or index if image_set is a list
              - value: (x,y,w,h) position and weight/height of image,
                 with left top corner of the block as (0,0), unit in mm
  
          ratio (bool): indicate grid specification by ratio
              instead of absolute size.
              If True, grid_width and grid_height are required.
  
          grid_width (int): width of the entire grid block (unit in mm)
  
          grid_height (int): height of the entire grid block (unit in mm)
  
          caption (str): caption of the entire grid block
  
          style (str): style of caption
      Returns:
          (bool) True if image blocks generate successfully, otherwise False
      """
  
      local_x = self.x
      local_y = self.y
  
      maximum_y = 0
      maximum_x = 0
  
      for image_name, (x, y, w, h) in grid_spec.items():
          for e in [x, y, w, h]:
              if type(e) not in [float, int]:
                  warnings.warn(
                      message="Error in image_spec: x,y,w,h "
                      "should all be int or float and non-negative."
                  )
                  return False
  
          if ratio:
              x *= grid_width
              y *= grid_height
              w *= grid_width
              h *= grid_height
              grid_spec[image_name] = (x, y, w, h)
              maximum_y = grid_height
              maximum_x = grid_width
          else:
              maximum_y = max(maximum_y, y + h)
  
      if local_x + maximum_x > self.w:
          warnings.warn(
              message="Error: figure will exceed the page edge "
              "on the right, exiting plotting."
          )
          return False
  
      if caption is None:
          if local_y + maximum_y > self.h - self.foot_size:
              warnings.warn(
                  message="Warning: figure will exceed the page bottom, "
                  "adding a new page."
              )
              self.add_page()
      else:
          if (
              self.y + maximum_y + CustomPdf.LINE_HEIGHT
              > self.h - self.foot_size
          ):
              warnings.warn(
                  message="Warning: figure will exceed the page bottom, "
                  "adding a new page."
              )
              self.add_page()
  
      if caption is not None:
          self.add_new_line(caption, style=style)
  
      local_x = self.x
      local_y = self.y
      if type(image_set) == dict:
          for image_name, image_path in image_set.items():
              if image_name not in grid_spec:
                  warnings.warn(
                      message="Error: Image name [%s] "
                      "not found in grid_spec." % image_name
                  )
                  return False
              pos = grid_spec[image_name]
              x, y, w, h = pos
              self.image(
                  image_set[image_name],
                  local_x + x,
                  local_y + y,
                  w,
                  h,
                  "",
                  "",
              )
  
      if type(image_set) == list:
          ## follow the index
          if len(image_set) != len(grid_spec):
              warnings.warn(
                  message="Error: Inconsistent length found. "
                  "Image set should be of same length with grid spec."
              )
          for idx, image_path in enumerate(image_set):
              if idx not in grid_spec:
                  warnings.warn(
                      message="Error: Image index [%s] "
                      "not found in grid_spec." % idx
                  )
                  return False
              pos = grid_spec[idx]
              x, y, w, h = pos
              self.image(
                  image_path, local_x + x, local_y + y, w, h, "", ""
              )
  
      self.ln(maximum_y)
      return True
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import os
  import warnings
  import datetime
  import re
  from fpdf import FPDF
label_desc: Use image node_id 19 for calling the CustomPdf obj's underlying member method code with example usage: obj.add_grid_images(image_set, grid_spec, ratio, grid_width, grid_height, caption, style) and returns: True, False, False, False, False