class_docstr: A ``Process`` type to capture everything
  that the ``stanza`` project can do for a
  given language.
  
  .. note::
      ``stanza`` has only partial functionality available for some languages.
  
  >>> from cltk.languages.example_texts import get_example_text
  >>> process_stanza = StanzaProcess(language="lat")
  >>> isinstance(process_stanza, StanzaProcess)
  True
  >>> from stanza.models.common.doc import Document
  >>> output_doc = process_stanza.run(Doc(raw=get_example_text("lat")))
  >>> isinstance(output_doc.stanza_doc, Document)
  True
class_docstr_tok: ["A","``","Process","``","type","to","capture","everything","that","the","``","stanza","``","project","can","do","for","a","given","language",".","..","note",":",":","``","stanza","``","has","only","partial","functionality","available","for","some","languages",".",">",">",">","from","cltk.languages.example_texts","import","get_example_text",">",">",">","process_stanza","=","StanzaProcess","(","language=","''","lat","''",")",">",">",">","isinstance","(","process_stanza",",","StanzaProcess",")","True",">",">",">","from","stanza.models.common.doc","import","Document",">",">",">","output_doc","=","process_stanza.run","(","Doc","(","raw=get_example_text","(","``","lat","''",")",")",")",">",">",">","isinstance","(","output_doc.stanza_doc",",","Document",")","True"]
docstr: Take an entire ``stanza`` document, extract
  each word, and encode it in the way expected by
  the CLTK's ``Word`` type.
  
  >>> from cltk.dependency.processes import StanzaProcess
  >>> from cltk.languages.example_texts import get_example_text
  >>> process_stanza = StanzaProcess(language="lat")
  >>> cltk_words = process_stanza.run(Doc(raw=get_example_text("lat"))).words
  >>> isinstance(cltk_words, list)
  True
  >>> isinstance(cltk_words[0], Word)
  True
  >>> cltk_words[0]
   Word(index_char_start=None, index_char_stop=None, index_token=0, index_sentence=0, string='Gallia', pos=noun, lemma='Gallia', stem=None, scansion=None, xpos='A1|grn1|casA|gen2', upos='NOUN', dependency_relation='nsubj', governor=1, features={Case: [nominative], Gender: [feminine], InflClass: [ind_eur_a], Number: [singular]}, category={F: [neg], N: [pos], V: [neg]}, stop=None, named_entity=None, syllables=None, phonetic_transcription=None, definition=None)
docstr_tok: ["Take","an","entire","``","stanza","``","document",",","extract","each","word",",","and","encode","it","in","the","way","expected","by","the","CLTK","'s","``","Word","``","type",".",">",">",">","from","cltk.dependency.processes","import","StanzaProcess",">",">",">","from","cltk.languages.example_texts","import","get_example_text",">",">",">","process_stanza","=","StanzaProcess","(","language=","''","lat","''",")",">",">",">","cltk_words","=","process_stanza.run","(","Doc","(","raw=get_example_text","(","``","lat","''",")",")",")",".words",">",">",">","isinstance","(","cltk_words",",","list",")","True",">",">",">","isinstance","(","cltk_words","[","0","]",",","Word",")","True",">",">",">","cltk_words","[","0","]","Word","(","index_char_start=None",",","index_char_stop=None",",","index_token=0",",","index_sentence=0",",","string='Gallia","'",",","pos=noun",",","lemma='Gallia","'",",","stem=None",",","scansion=None",",","xpos='A1|grn1|casA|gen2","'",",","upos='NOUN","'",",","dependency_relation='nsubj","'",",","governor=1",",","features=","{","Case",":","[","nominative","]",",","Gender",":","[","feminine","]",",","InflClass",":","[","ind_eur_a","]",",","Number",":","[","singular","]","}",",","category=","{","F",":","[","neg","]",",","N",":","[","pos","]",",","V",":","[","neg","]","}",",","stop=None",",","named_entity=None",",","syllables=None",",","phonetic_transcription=None",",","definition=None",")"]
code: def stanza_to_cltk_word_type(stanza_doc):
      """Take an entire ``stanza`` document, extract
      each word, and encode it in the way expected by
      the CLTK's ``Word`` type.
  
      >>> from cltk.dependency.processes import StanzaProcess
      >>> from cltk.languages.example_texts import get_example_text
      >>> process_stanza = StanzaProcess(language="lat")
      >>> cltk_words = process_stanza.run(Doc(raw=get_example_text("lat"))).words
      >>> isinstance(cltk_words, list)
      True
      >>> isinstance(cltk_words[0], Word)
      True
      >>> cltk_words[0]
       Word(index_char_start=None, index_char_stop=None, index_token=0, index_sentence=0, string='Gallia', pos=noun, lemma='Gallia', stem=None, scansion=None, xpos='A1|grn1|casA|gen2', upos='NOUN', dependency_relation='nsubj', governor=1, features={Case: [nominative], Gender: [feminine], InflClass: [ind_eur_a], Number: [singular]}, category={F: [neg], N: [pos], V: [neg]}, stop=None, named_entity=None, syllables=None, phonetic_transcription=None, definition=None)
  
      """
  
      words_list = list()  # type: List[Word]
  
      for sentence_index, sentence in enumerate(stanza_doc.sentences):
          sent_words = dict()  # type: Dict[int, Word]
          indices = list()  # type: List[Tuple[int, int]]
  
          for token_index, token in enumerate(sentence.tokens):
              stanza_word: stanza.pipeline.doc.Word = token.words[0]
              # TODO: Figure out how to handle the token indexes, esp 0 (root) and None (?)
              pos: Optional[MorphosyntacticFeature] = None
              if stanza_word.pos:
                  pos = from_ud("POS", stanza_word.pos)
              cltk_word = Word(
                  index_token=int(stanza_word.id)
                  - 1,  # subtract 1 from id b/c Stanza starts their index at 1
                  index_sentence=sentence_index,
                  string=stanza_word.text,  # same as ``token.text``
                  pos=pos,
                  xpos=stanza_word.xpos,
                  upos=stanza_word.upos,
                  lemma=stanza_word.lemma
                  if stanza_word.lemma
                  else stanza_word.text,
                  dependency_relation=stanza_word.deprel,
                  governor=stanza_word.head - 1
                  if stanza_word.head
                  else -1,  # note: if val becomes ``-1`` then no governor, ie word is root
              )
  
              # convert UD features to the normalized CLTK features
              raw_features = (
                  [
                      tuple(f.split("="))
                      for f in stanza_word.feats.split("|")
                  ]
                  if stanza_word.feats
                  else []
              )
  
              cltk_features = [
                  from_ud(feature_name, feature_value)
                  for feature_name, feature_value in raw_features
              ]
              cltk_word.features = MorphosyntacticFeatureBundle(
                  *cltk_features
              )
              cltk_word.category = to_categorial(cltk_word.pos)
              cltk_word.stanza_features = stanza_word.feats
  
              # sent_words[cltk_word.index_token] = cltk_word
              words_list.append(cltk_word)
  
              # # TODO: Fix this, I forget what we were tracking in this
              # indices.append(
              #     (
              #         int(stanza_word.governor)
              #         - 1,  # -1 to match CLTK Word.index_token
              #         int(stanza_word.parent_token.index)
              #         - 1,  # -1 to match CLTK Word.index_token
              #     )
              # )
          # # TODO: Confirm that cltk_word.parent is ever getting filled out. Only for some lang models?
          # for idx, cltk_word in enumerate(sent_words.values()):
          #     governor_index, parent_index = indices[idx]  # type: int, int
          #     cltk_word.governor = governor_index if governor_index >= 0 else None
          #     if cltk_word.index_token != sent_words[parent_index].index_token:
          #         cltk_word.parent = parent_index
  
      return words_list
  
imports: from copy import deepcopy
  from dataclasses import dataclass
  from typing import Any, Dict, List, Literal, Optional, Tuple
  import spacy
  import stanza
  from boltons.cacheutils import cachedproperty
  from cltk.core.data_types import Doc, MorphosyntacticFeature, Process, Word
  from cltk.dependency.spacy_wrapper import SpacyWrapper
  from cltk.dependency.stanza_wrapper import StanzaWrapper
  from cltk.dependency.tree import DependencyTree
  from cltk.morphology.morphosyntax import MorphosyntacticFeatureBundle, from_ud, to_categorial
label_desc: Use image node_id 3 for calling the StanzaProcess obj's underlying member method code with example usage: obj.stanza_to_cltk_word_type(stanza_doc) and returns: words_list