docs: def stylemap(self, definitions=True, all=True, cache=False):
          """return a dictionary of styles from .docx word/styles.xml, keyed to the id
          (the id is used in the .docx word/document.xml rather than the style names; 
          this method creates a mapping for us to use when outputting the document).
          if definitions==True (default), then style definitions are also included.
          if all==False, then only those styles that are used are included (slower).
          """
          if self._stylemap is not None and cache==True:
              return self._stylemap
          else:
              self._stylemap = None              # expire the cache
              x = self.xml(src='word/styles.xml')
              document = self.xml(src='word/document.xml')
              footnotes = self.xml(src='word/footnotes.xml')  # None if no footnotes
              endnotes = self.xml(src='word/endnotes.xml')    # None if no endnotes
              d = Dict()
              for s in x.root.xpath("w:style", namespaces=self.NS):
                  style = Dict()
                  style.id = s.get("{%(w)s}styleId" % self.NS)
                  style.type = s.get("{%(w)s}type" % self.NS)
                  style.xpath = "//w:rStyle[@w:val='%(id)s'] | //w:pStyle[@w:val='%(id)s']" % style
                  if all == False:
                      uses = document.root.xpath(style.xpath, namespaces=DOCX.NS)
                      if len(uses)==0:
                          # try footnotes and endnotes
                          if footnotes is not None:
                              uses = footnotes.root.xpath(style.xpath, namespaces=DOCX.NS)
                          if len(uses)==0:
                              if endnotes is not None:
                                  uses = endnotes.root.xpath(style.xpath, namespaces=DOCX.NS)
                              if len(uses)==0:
                                  continue
                  LOG.debug("%s %r" % (s.tag, s.attrib))
                  style.name = XML.find(s, "w:name/@w:val", namespaces=self.NS)
                  if style.name is None:
                      LOG.debug("style without name: %r" % style)
                  d[style.id] = style
                  LOG.debug(style)
                  if definitions is True: 
                      bo = s.find("{%(w)s}basedOn" % DOCX.NS)
                      if bo is not None:
                          style.basedOn = bo.get("{%(w)s}val" % DOCX.NS)
                      style.properties = Dict()
                      for pr in s.xpath("w:pPr/* | w:rPr/*", namespaces=DOCX.NS):
                          tag = re.sub(r"^\{[^}]*\}", "", pr.tag)
                          props = Dict()
                          for attr in pr.attrib.keys():
                              k = re.sub(r"^\{[^}]*\}", "", attr)
                              props[k] = pr.get(attr)
                          style.properties[tag] = props
              if cache is True: 
                  self._stylemap = d
              return d