class_docstr: Handles chunking by adding a new set of offsets system keyed by "chunk"
  Performs chunking based on the following rules
  
  * Select longest axis of the table, rows or columns
  * For this longest axis, chunk such that each chunk's effective num tokens is less than the defined max_length
  * effective num tokens is the number of tokens you get if you duplicate tokens by the number of cells they span.
  * Each chunk get's n_rows_context rows of context from the beginning of the opposite axis to the one being chunked (2 rows of context if columns are chunked)
  * If n_rows_context takes up more than max_length / 2 effective tokens then this context is backed off until the amount of context is less than max_length / 2.
  
  
  There is no invese chunking as TableETL.resolve_preds will simply map directly from chunk to document if chunking is enabled.
code: def chunk(self, table_text_chunks_and_context):
      texts = []
      if "table_labels" in table_text_chunks_and_context:
          labels = []
      else:
          labels = None
      contexts = []
      doc_is = []
      chunks = []
  
      for text, label, context, doc_i, chunk in zip(
          table_text_chunks_and_context["table_text"],
          table_text_chunks_and_context.get(
              "table_labels",
              [None] * len(table_text_chunks_and_context["table_text"]),
          ),
          table_text_chunks_and_context["table_context"],
          table_text_chunks_and_context["table_doc_i"],
          table_text_chunks_and_context["table_chunks"],
      ):
          tokens = self.tokenizer.encode_multi_input(
              [text],
              max_length=sys.maxsize,
              remove_repeated_whitespace=True,
              include_bos_eos=False,
          )
          token_bounds = [
              {"start": s, "end": e}
              for s, e in zip(tokens.token_starts, tokens.token_ends)
          ]
          combined_row_spans = self.get_axis_spans(
              context=context,
              token_bounds=token_bounds,
              context_key="start_row",
          )
          combined_col_spans = self.get_axis_spans(
              context=context,
              token_bounds=token_bounds,
              context_key="start_col",
          )
          if max(
              r["num_effective_tokens"] for r in combined_row_spans
          ) > max(
              c["num_effective_tokens"] for c in combined_col_spans
          ):
              # Split along the narrowest axis.
              combined_axis_spans = combined_col_spans
          else:
              combined_axis_spans = combined_row_spans
  
          spans = self._make_chunks(combined_axis_spans)
          for chunk_spans in spans:
              new_chunk_mapping = self._create_chunk_mappings(
                  chunk, chunk_spans
              )
              if len(chunk_spans) == 0 or len(new_chunk_mapping) == 0:
                  continue
              chunk_text = "\n".join(
                  text[c["table"]["start"] : c["table"]["end"]]
                  for c in new_chunk_mapping
              )
              texts.append(chunk_text)
              if labels is not None:
                  labels.append(
                      fix_spans(
                          label,
                          new_chunk_mapping,
                          output_space="chunk",
                          input_space="table",
                          output_space_text=chunk_text,
                      )
                  )
              contexts.append(
                  fix_spans(
                      context,
                      new_chunk_mapping,
                      output_space="chunk",
                      input_space="table",
                      output_space_text=chunk_text,
                  )
              )
              doc_is.append(doc_i)
              chunks.append(new_chunk_mapping)
      if labels is not None:
          label_output = {"table_labels": labels}
      else:
          label_output = dict()
  
      return {
          **table_text_chunks_and_context,
          **label_output,
          "table_text": texts,
          "table_chunks": chunks,
          "table_context": contexts,
          "table_doc_i": doc_is,
      }
  
imports: import copy
  import functools
  import os
  import tempfile
  import typing
  import sys
  from finetune.base_models import TableRoBERTa
  from finetune.util.metrics import sequences_overlap
  from finetune.scheduler import Scheduler
  from finetune.encoding.input_encoder import BaseEncoder
  from finetune import SequenceLabeler
label_desc: Use image node_id 3 for calling the TableChunker obj's underlying member method code with example usage: obj.chunk(table_text_chunks_and_context) and returns: dict