code: def semistructured_statements(
      doclike: types.DocLike,
      *,
      entity: str | Pattern,
      cue: str,
      fragment_len_range: Optional[
          tuple[Optional[int], Optional[int]]
      ] = None,
  ) -> Iterable[SSSTriple]:
      """
      Extract "semi-structured statements" from a document as a sequence of
      (entity, cue, fragment) triples.
  
      Args:
          doclike
          entity: Noun or noun phrase of interest expressed as a regular expression
              pattern string (e.g. ``"[Gg]lobal [Ww]arming"``) or compiled object
              (e.g. ``re.compile("global warming", re.IGNORECASE)``).
          cue: Verb lemma with which ``entity`` is associated (e.g. "be", "have", "say").
          fragment_len_range: Filter statements to those whose fragment length in tokens
              is within the specified [low, high) interval. Both low and high values
              must be specified, but a null value for either is automatically replaced
              by safe default values. None (default) skips filtering by fragment length.
  
      Yields:
          Next matching triple, consisting of (entity, cue, fragment),
          in order of appearance.
  
      Notes:
          Inspired by N. Diakopoulos, A. Zhang, A. Salway. Visual Analytics of
          Media Frames in Online News and Blogs. IEEE InfoVis Workshop on Text
          Visualization. October, 2013.
  
          Which itself was inspired by by Salway, A.; Kelly, L.; Skadiņa, I.; and
          Jones, G. 2010. Portable Extraction of Partially Structured Facts from
          the Web. In Proc. ICETAL 2010, LNAI 6233, 345-356. Heidelberg, Springer.
      """
      if fragment_len_range is not None:
          fragment_len_range = utils.validate_and_clip_range(
              fragment_len_range, (1, 1000), int
          )
      for entity_cand in matches.regex_matches(
          doclike, entity, alignment_mode="strict"
      ):
          # is the entity candidate a nominal subject?
          if entity_cand.root.dep in _NOMINAL_SUBJ_DEPS:
              cue_cand = entity_cand.root.head
              # is the cue candidate a verb with matching lemma?
              if cue_cand.pos in {VERB, AUX} and cue_cand.lemma_ == cue:
                  frag_cand = None
                  for tok in cue_cand.children:
                      if (
                          tok.dep in {attr, dobj, obj}
                          or tok.dep_ == "dative"
                          or (
                              tok.dep == xcomp
                              and not any(
                                  child.dep == dobj
                                  for child in cue_cand.children
                              )
                          )
                      ):
                          subtoks = list(tok.subtree)
                          if (
                              fragment_len_range is None
                              or fragment_len_range[0]
                              <= len(subtoks)
                              < fragment_len_range[1]
                          ):
                              frag_cand = subtoks
                              break
                  if frag_cand is not None:
                      yield SSSTriple(
                          entity=list(entity_cand),
                          cue=sorted(
                              expand_verb(cue_cand), key=attrgetter("i")
                          ),
                          fragment=sorted(
                              frag_cand, key=attrgetter("i")
                          ),
                      )
  
file_path: textacy/src/textacy/extract/triples.py
imports: from __future__ import annotations
  import collections
  from operator import attrgetter
  from typing import Iterable, Mapping, Optional, Pattern
  from cytoolz import itertoolz
  from spacy.symbols import AUX, VERB, agent, attr, aux, auxpass, csubj, csubjpass, dobj, neg, nsubj, nsubjpass, obj, pobj, xcomp
  from spacy.tokens import Doc, Span, Token
  from ..None import constants, types, utils
  from .None import matches
label_desc: Use image node_id 2 for calling a global function with example usage: semistructured_statements(doclike) without return types