code: def ctcTokenPassing(
      mat, classes, charWords, blankIdx=-1, word_separator=" "
  ):
      """implements CTC Token Passing Algorithm as shown by Graves (Dissertation, p67-69)"""
      if blankIdx < 0:
          blankIdx = len(classes)
      maxT, _ = mat.shape
  
      # special s index for beginning and end of word
      beg = 0
      end = -1
  
      # map characters to labels for each word
      words = [wordToLabelSeq(w, classes) for w in charWords]
  
      # w' in paper: word with blanks in front, back and between labels: for -> _f_o_r_
      primeWords = [extendByBlanks(w, blankIdx) for w in words]
  
      # data structure holding all tokens
      toks = TokenList()
  
      # Initialisation: 1-9
      for wIdx, w in enumerate(words):
          w = words[wIdx]
          wPrime = primeWords[wIdx]
  
          # set all toks(w,s,t) to init state
          for s in range(len(wPrime)):
              for t in range(maxT):
                  toks.set(wIdx, s + 1, t + 1, Token())
                  toks.set(wIdx, beg, t, Token())
                  toks.set(wIdx, end, t, Token())
  
          toks.set(wIdx, 1, 1, Token(log(mat[1 - 1, blankIdx]), [wIdx]))
          cIdx = w[1 - 1]
          toks.set(wIdx, 2, 1, Token(log(mat[1 - 1, cIdx]), [wIdx]))
  
          if len(w) == 1:
              toks.set(wIdx, end, 1, toks.get(wIdx, 2, 1))
  
      # Algorithm: 11-24
      t = 2
      while t <= maxT:
          sortedWordIdx = outputIndices(toks, words, end, t - 1)
  
          for wIdx in sortedWordIdx:
              wPrime = primeWords[wIdx]
  
              # 15-17
              # if bigrams should be used, these lines have to be adapted
              bestOutputTok = toks.get(sortedWordIdx[-1], end, t - 1)
              wBestPrime = primeWords[sortedWordIdx[-1]]
              toks.set(
                  wIdx,
                  beg,
                  t,
                  Token(
                      bestOutputTok.score,
                      bestOutputTok.history + [wIdx],
                  ),
              )
  
              # 18-24
              s = 1
              while s <= len(wPrime):
                  if s == 1:
                      P = [
                          toks.get(wIdx, 1, t - 1),
                          toks.get(wIdx, 0, t),
                      ]
                  else:
                      P = [
                          toks.get(wIdx, s, t - 1),
                          toks.get(wIdx, s - 1, t - 1),
                      ]
                      # allow direct transition in state 2 (first char) if the last word ended with another char
                      if s == 2 and (wBestPrime[-2] != wPrime[1]):
                          P.append(toks.get(wIdx, 0, t))
  
                  if (
                      wPrime[s - 1] != blankIdx
                      and s > 2
                      and wPrime[s - 2 - 1] != wPrime[s - 1]
                  ):
                      tok = toks.get(wIdx, s - 2, t - 1)
                      P.append(Token(tok.score, tok.history))
  
                  maxTok = max(P, key=lambda x: x.score)
                  cIdx = wPrime[s - 1]
  
                  score = maxTok.score + log(mat[t - 1, cIdx])
                  history = maxTok.history
  
                  toks.set(wIdx, s, t, Token(score, history))
                  s += 1
  
              maxTok = max(
                  [
                      toks.get(wIdx, len(wPrime), t),
                      toks.get(wIdx, len(wPrime) - 1, t),
                  ],
                  key=lambda x: x.score,
              )
              toks.set(wIdx, end, t, maxTok)
  
          t += 1
  
      # Termination: 26-28
      bestWIdx = outputIndices(toks, words, end, maxT)[-1]
      return word_separator.join(
          [charWords[i] for i in toks.get(bestWIdx, end, maxT).history]
      )
  
file_path: calamari/calamari_ocr/ocr/model/ctcdecoder/token_passing_ctc_decoder.py
imports: import math
  import numpy
  from calamari_ocr.ocr.model.ctcdecoder.ctc_decoder import CTCDecoder
label_desc: Use image node_id 5 for calling a global function with example usage: ctcTokenPassing(mat, classes, charWords, blankIdx, word_separator) and returns: word_separator