class_docstr: Currently supports validation for: hexameter, hendecasyllables, pentameter.
class_docstr_tok: ["Currently","supports","validation","for",":","hexameter",",","hendecasyllables",",","pentameter","."]
docstr: Produces a list of hexameter feet, stressed and unstressed syllables with spaces intact.
  If the scansion line is not entirely correct, it will attempt to corral one or more improper patterns into one or more feet.
  
  :param: scansion, the scanned line
  
  :return list of strings, representing the feet of the hexameter, or if the scansion is wildly incorrect, the function will return an empty list.
  
  >>> print("|".join(MetricalValidator().hexameter_feet(
  ... "- U U   -     -  - -   -  -     - U  U  -  U")).strip() )
  - U U   |-     -  |- -   |-  -     |- U  U  |-  U
  >>> print("|".join(MetricalValidator().hexameter_feet(
  ... "- U U   -     -  U -   -  -     - U  U  -  U")).strip())
  - U U   |-     -  |U -   |-  -     |- U  U  |-  U
docstr_tok: ["Produces","a","list","of","hexameter","feet",",","stressed","and","unstressed","syllables","with","spaces","intact",".","If","the","scansion","line","is","not","entirely","correct",",","it","will","attempt","to","corral","one","or","more","improper","patterns","into","one","or","more","feet",".",":","param",":","scansion",",","the","scanned","line",":","return","list","of","strings",",","representing","the","feet","of","the","hexameter",",","or","if","the","scansion","is","wildly","incorrect",",","the","function","will","return","an","empty","list",".",">",">",">","print","(","``","|","''",".join","(","MetricalValidator","(",")",".hexameter_feet","(","...","``","-","U","U","-","-","-","-","-","-","-","U","U","-","U","''",")",")",".strip","(",")",")","-","U","U","|-","-","|-","-","|-","-","|-","U","U","|-","U",">",">",">","print","(","``","|","''",".join","(","MetricalValidator","(",")",".hexameter_feet","(","...","``","-","U","U","-","-","U","-","-","-","-","U","U","-","U","''",")",")",".strip","(",")",")","-","U","U","|-","-","|U","-","|-","-","|-","U","U","|-","U"]
code: def hexameter_feet(self, scansion: str) -> List[str]:
      """
      Produces a list of hexameter feet, stressed and unstressed syllables with spaces intact.
      If the scansion line is not entirely correct, it will attempt to corral one or more improper patterns into one or more feet.
  
      :param: scansion, the scanned line
  
      :return list of strings, representing the feet of the hexameter, or if the scansion is wildly incorrect, the function will return an empty list.
  
      >>> print("|".join(MetricalValidator().hexameter_feet(
      ... "- U U   -     -  - -   -  -     - U  U  -  U")).strip() )
      - U U   |-     -  |- -   |-  -     |- U  U  |-  U
      >>> print("|".join(MetricalValidator().hexameter_feet(
      ... "- U U   -     -  U -   -  -     - U  U  -  U")).strip())
      - U U   |-     -  |U -   |-  -     |- U  U  |-  U
  
      """
      backwards_scan = list(scansion.rstrip())
      feet = []
      candidates = [
          self.constants.STRESSED + self.constants.OPTIONAL_ENDING,
          self.constants.STRESSED + self.constants.STRESSED,
          self.constants.STRESSED + self.constants.UNSTRESSED,
          self.constants.UNSTRESSED + self.constants.STRESSED,
      ]
      incomplete_foot = (
          self.constants.UNSTRESSED + self.constants.UNSTRESSED
      )
      try:
          while len(backwards_scan) > 0:
              spaces = []
              chunk1 = backwards_scan.pop()
              while len("".join(chunk1).replace(" ", "")) == 0:
                  if len(backwards_scan) == 0:
                      feet.append(chunk1)
                      return feet[::-1]
                  chunk1 = backwards_scan.pop() + "".join(chunk1)
              chunk2 = backwards_scan.pop()
              while chunk2 == " ":
                  spaces.append(chunk2)
                  if len(backwards_scan) == 0:
                      feet.append(chunk2)
                      return feet[::-1]
                  chunk2 = backwards_scan.pop()
              new_candidate = (
                  "".join(chunk2) + "".join(spaces) + "".join(chunk1)
              )
              if new_candidate.replace(" ", "") in candidates:
                  feet.append(new_candidate)
              else:
                  if new_candidate.replace(" ", "") == incomplete_foot:
                      spaces2 = []
                      previous_mark = backwards_scan.pop()
                      while previous_mark == " ":
                          spaces2.append(previous_mark)
                          previous_mark = backwards_scan.pop()
                      if previous_mark == self.constants.STRESSED:
                          new_candidate = (
                              "".join(previous_mark)
                              + "".join(spaces2)
                              + new_candidate
                          )
                          feet.append(new_candidate)
                      else:
                          feet.append(new_candidate)  # invalid foot
                          spaces3 = []
                          next_mark = backwards_scan.pop()
                          while next_mark == " ":
                              spaces3.append(previous_mark)
                              next_mark = backwards_scan.pop()
                          feet.append(
                              "".join(next_mark)
                              + "".join(spaces3)
                              + previous_mark
                          )
      except Exception as ex:
          LOG.error("err at: {}, {}".format(scansion, ex))
          return list()
      return feet[::-1]
  
file_path: cltk/src/cltk/prosody/lat/metrical_validator.py
imports: import logging
  from typing import List
  from rapidfuzz.distance import DamerauLevenshtein
  from cltk.prosody.lat.scansion_constants import ScansionConstants
label_desc: Use image node_id 5 for calling the MetricalValidator obj's underlying member method code with example usage: obj.hexameter_feet(scansion) and returns: feet, list, feet, feet