agentleFS
jyjeannejyjeanne/dita-skills/map-resolve/SKILL.md

map-resolve

Skill2 starsChanged 6 months agoMITView on GitHub

Reference skill for pydita's resolvemap module. Use this skill when you need to flatten a DITA map tree into a single in-memory document using resolveMap(), understand how submaps are inlined as topicgroup elements, apply DITAVAL filtering during resolution, or discover all files referenced by a map with getDirectFilesFromMap().

The file

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 0 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈0

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    If no filter is provided, a pass-through DitavalFilter() (includes everything) is used automatically.

    line 76
  2. Very specific:

    All paths are absolute. The root map itself is included in "maps".

    line 93

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Overview

pydita.resolvemap flattens a tree of DITA maps (root map + submaps) into a single ElementTree. This is equivalent to what the XSLT resolve-map.xsl library does in DITA-OT. The resolved map is the required input for KeyspaceManager.


resolveMap() — API reference

from pydita import resolvemap

resolved: ElementTree = resolvemap.resolveMap(
    rootmap,           # str path, IOBase file, or ElementTree
    ditavalFilter,     # DitavalFilter — default: pass-through (include everything)
    errors,            # dict — collects errors keyed by file path
    debug,             # bool — default False
)

rootmap input forms

FormExample
File path string"docs/root.ditamap"
Open file objectopen("docs/root.ditamap")
Parsed ElementTreeresult of etree.parse(...)

Any other type raises Exception("Value … is not a recognized type").

Return value

An ElementTree whose root element mirrors the root map element, with all local-scope format="ditamap" references replaced inline by a <topicgroup base="submap"> wrapper containing the submap's children.


How submaps are inlined

Each local submap reference (<topicref format="ditamap" scope="local" href="sub.ditamap"/>) becomes:

<topicgroup class="+ map/topicref mapgroup-d/topicgroup " base="submap"
            orig-href="sub.ditamap" orig-class="- map/topicref ">
  <topicmeta class="- map/topicmeta ">
    <navtitle class="- topic/navtitle ">Submap Title</navtitle>
  </topicmeta>
  <!-- submap's topicrefs and reltables copied here -->
</topicgroup>

Key attributes on the topicgroup:

  • base="submap" — marker used by ditautils to detect inlined submaps
  • orig-href — original href to the submap file
  • xml:base — set to the submap's absolute URI so relative href values resolve correctly

DITAVAL filtering during resolution

Elements excluded by the filter are not copied into the resolved map. This means excluded submaps are not resolved at all.

from pydita.ditaval import DitavalFilter

# Build a filter from a .ditaval file
filter = DitavalFilter(ditavalFiles=["filters/internal.ditaval"], errors=errors)

resolved = resolvemap.resolveMap("root.ditamap", ditavalFilter=filter, errors=errors)

If no filter is provided, a pass-through DitavalFilter() (includes everything) is used automatically.


getDirectFilesFromMap() — discover referenced files

from pydita import ditautils

result = ditautils.getDirectFilesFromMap(resolved_map, errors=errors)
# result = {
#   "topics":   {"/abs/path/to/topic.dita", ...},
#   "maps":     {"/abs/path/to/root.ditamap", "/abs/path/to/sub.ditamap", ...},
#   "nondita":  {"/abs/path/to/image.png", ...},
# }

All paths are absolute. The root map itself is included in "maps".


Error handling

Parsing errors are recorded in the errors dict and re-raised as ParseError for submap failures. Always check errors after resolveMap():

errors = {}
resolved = resolvemap.resolveMap("root.ditamap", errors=errors)
if errors:
    from pydita import loggingutils
    print(loggingutils.reportErrors(errors))

Known limitation: the # FIXME in resolveMap() means root-map ParseError is recorded but not re-raised. A None resolved map after the call indicates a root-map parse failure.


Common errors

ErrorCauseFix
KeyError: 'DITA_OT_DIR'DITA-OT not found by getDTDAwareParser()Set DITA_OT_DIR env var or add to ~/.build.properties
ParseError on submapSubmap XML is malformed or not foundCheck orig-href paths are relative to the parent map
Resolved map missing contentSubmap excluded by DITAVAL filterCheck filter conditions match submap's conditional attributes
Keys not found after resolutionSubmap was not resolved (peer/external scope)Only scope="local" submaps are inlined

See also

  • context-setup — how to pass the resolved map into KeyspaceManager and DitaContext
  • keyspace-debug — inspect the key spaces built from the resolved map

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.