Cross referencing in LaTeX uses quite simple schema - for every label it stores value of macro \@currentlabel and the page number in the aux file. There are packages, which extends this scheme, like titleref or zref, but it is still just label and some properties, which are then accessed with some form of \ref command.
What would be useful in this case, is something like RDF so one can construct complex graph of objects, their properties and relationships, like
Theorem Lorem is defined in the Section Ipsum on page 4 and it has
Definition foo on page 5 and Example boo on page 6, is referenced on
pages 3,7,89 etc...
In this model every label (object) can have any number of properties, which can be values, or other objects, which gives us directed graph of objects, properties and subjects. objects and properties are in form of prefix:name,
Now there is some simple rdf framework for LaTeX
First we define some core functions for saving and loading properties
rdfref-core.sty
\ProvidesPackage{rdfref-core}
\RequirePackage{etoolbox}
\def\Nil{}%
\def\First#1#2{#1}
\def\Second#1#2{#2}
\def\parsecolon#1:#2\relax{\ifx#2\Nil\Nil\else#1\fi}%
\newcommand\RdfPrefix[1]{%
\parsecolon#1:\Nil\relax%
}
\newcommand\AddTriple[3]{%
\edef\rdf@object{#3}
\immediate\write\@auxout{\noexpand\LoadTriple{#1}{#2}{\rdf@object}}
}
\newcommand\SetProperty[3]{%
\protected@csxdef{rdf@#1@#2}{#3}%
}
\newcommand\GetProperty[2]{%
\ifcsdef{rdf@#1@#2}{%
\csuse{rdf@#1@#2}%
}{%
\PropertyNotDef{#1}{#2}%
}%
}
\newcommand\PropertyNotDef[2]{%
???%
%\typeout{rdf warning: subject #1 has no property #2}%
}
\newcommand\SubjectListAdd[2]{%
\listcsgadd{sbjlst@#1}{#2}
}
\newcommand\MapSubjectList[2]{%
\def\do##1{#2}%
\dolistcsloop{sbjlst@#1}%
}
\newcommand\PropertyListAdd[3]{%
\listcsgadd{prprtlst@#2}{{#1}{#3}}
}
\newcommand\MapPropertyList[2]{%
\def\do##1{#2}%
\dolistcsloop{prprtlst@#1}%
}
\newcommand\LoadTriple[3]{%
\SetProperty{#1}{#2}{#3}
\SubjectListAdd{#1}{#2}
\PropertyListAdd{#1}{#2}{#3}
}
Two useful functions are \MapPropertyList, which lets you to loop over all objects and subjects with given property and \MapSubjectList for loop over properties of given subject.
Now some helper functions, which emulates somehow latex cross-referencing system rdfref-user.sty:
\ProvidesPackage{rdfref-user}
\RequirePackage{rdfref-core,nameref}
\newwrite\exportfile
\def\RootObject{_:doc}
\def\CurrentObject{\RootObject}
\newcommand\AddRdfType[2]{%
\def\do##1{\csgdef{rdf:type@##1}{\noexpand\unexpanded{#2}}}
%\csgdef{rdf:type@#1}{\unexpanded{#2}}
\docsvlist{#1}
}
\newcommand\AddProperty[2]{%
\AddTriple{\CurrentObject}{#1}{#2}
}
\newcommand\WithObject[2]{%
\begingroup%
\def\CurrentObject{#1}%
\def\run{#2}
\run%
\endgroup%
}
\newcommand\rdflabel[1]{%
\AddTriple{#1}{doc:hasParent}{\CurrentObject}%
\AddTriple{#1}{doc:envir}{\@currenvir}%
\def\CurrentObject{#1}%
\ifcsdef{rdf:type@\GuessRdfType{#1}}%
{\csuse{rdf:type@\GuessRdfType{#1}}}%
{\typeout{Package rdfref error: unknown type of reference #1 :\GuessRdfType{#1}:}}%
\label{#1}
}
\newcommand\GuessRdfType[1]{%
% We first try if current environment is defined as type, if not, then guess type from the parameter
\ifcsdef{rdf:type@\@currenvir}{\@currenvir}{%
\ifx\RdfPrefix{#1}\Nil\Nil\else%
\RdfPrefix{#1}%
\fi%
}%
}
\newcommand\inputontology[1]{%
\makeatletter
\input{#1}
\makeatother
}
command \rdflabel constructs LaTeX label, so you can use normal constructs like \ref and \pageref and creates object with some default values and then call constructor which stores properties which are defined for object of given type. Type is deducted from object's surrounding environment, if it doesn't have set type, it is deducted from its prefix.
These constructors are defined in ontologies, which are normal TeX files with macro definitions, but which must be loaded after \begin{document}, because they need to write to the aux file.
theorem-ontology.tex
\newcommand\partOf[1]{%
\AddProperty{doc:partOf}{#1}
}
\AddRdfType{Theorem}{%
\AddProperty{rdf:type}{thm:theorem}
\AddProperty{doc:pageNo}{\thepage}
\AddProperty{rdfs:label}{\@currentlabel\ \@currentlabelname}
}
\AddRdfType{thr}{%
\AddProperty{rdf:type}{thm:theorem}
\AddProperty{doc:pageNo}{\thepage}
\AddProperty{rdfs:label}{\@currentlabel\ \@currentlabelname}
}
\AddRdfType{prop}{%
\AddProperty{rdf:type}{thm:proposition}
\AddProperty{doc:pageNo}{\thepage}
\AddProperty{rdfs:label}{\@currentlabel\ \@currentlabelname}
}
\AddRdfType{lem}{%
\AddProperty{rdf:type}{thm:lemma}
\AddProperty{doc:pageNo}{\thepage}
\AddProperty{rdfs:label}{\@currentlabel\ \@currentlabelname}
}
\AddRdfType{sec}{
\AddProperty{rdf:type}{sec:sectioning}
\AddProperty{doc:pageNo}{\thepage}
\AddProperty{rdfs:label}{\@currentlabel\ \@currentlabelname}
\AddProperty{doc:label}{\@currentlabel}
}
\AddRdfType{equation}{%
\AddProperty{rdf:type}{eq:equation}
\AddProperty{doc:pageNo}{\thepage}
\AddProperty{rdfs:label}{\@currentlabel\ \@currentlabelname}
}
\WithObject{sec:sectioning}{%
\AddProperty{rdfs:label}{Sectioning}
\AddProperty{rdf:type}{rdfs:Class}
}
\WithObject{thm:theorem}{%
\AddProperty{rdfs:label}{Theorem}
\AddProperty{rdf:type}{rdfs:Class}
}
\WithObject{thm:proposition}{%
\AddProperty{rdfs:label}{Proposition}
\AddProperty{rdf:type}{rdfs:Class}
}
\WithObject{thm:lemma}{%
\AddProperty{rdfs:label}{Lemma}
\AddProperty{rdf:type}{rdfs:Class}
}
\WithObject{eq:equation}{%
\AddProperty{rdfs:label}{Equation}
\AddProperty{rdf:type}{rdfs:Class}
}
\WithObject{rdfs:Class}{%
\AddProperty{rdfs:label}{Class}
}
you can see that we added constructors for some environments and prefixes. important property is rdf:type, which can be used for example if you want to loop over all theorems or equations. there are also properties doc:pageNo and rdfs:label, which are more or less traditional LaTeX cross-referencing properties. For every rdf:object there is also \WithObject macro, which set textual labels (rdfs:label) for these types.
there is also command \partOf, which declares current object as part of another object. It can be used in examples or definitions, to declare that they are part of some theorem. I do really know nothing about mathematical theorems, so this is really just an simple example, not anything useful. If you have idea about some useful properties, they can be easily added.
Now some sample file:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[]{tgschola}
\usepackage[T1]{fontenc}
%\catcode`\_=12
\usepackage[]{rdfref-user,lipsum,nameref,cleveref}
\usepackage{amsthm,thmtools,xstring}
\declaretheorem[name=Lemma,Refname={Lemma,Lemmas}]{lem}
\declaretheorem[name=Proposition,Refname={Proposition,Proposition}]{prop}
\declaretheorem[name=Theorem,Refname={Theorem,Theorems}]{thr}
\begin{document}
\inputontology{theorem-ontology.tex}
\section{Hello world}\rdflabel{sec:first}
\lipsum[1-2]
\begin{lem}\rdflabel{thm:lem1}
\partOf{thm:thr1}
A lemma.
\end{lem}
\begin{prop}
\rdflabel{thm:prop1}
\partOf{thm:thr1}
A proposition.
%\renewcommand{\theenumi}{\thecor.\arabic{enumi}}
\begin{enumerate}
\item An item
\item Another one
\end{enumerate}
\end{prop}
\begin{thr}\rdflabel{thm:thr1}
A theorem.
\end{thr}
\begin{thr}[Euclid]
\rdflabel{thm:euclid}%
For every prime $p$, there is a prime $p’>p$.
In particular, the list of primes,
\begin{equation}\rdflabel{eq:1}
2,3,5,7,\dots
\end{equation}
is infinite.
\end{thr}
\end{document}
And if you want to export some graph, try this macro (Not much nice, but it shows some ways, how you can work with your properties graph):
\newcommand\ExportGraphviz[2]{%
digraph G\{
\forcsvlist{\listadd\typelist}{#1}
%\forcsvlist{\listadd\propertylist}{#2}
\def\worker##1##2{%
%"\ObjectLabel" -> \GetProperty{\First##1}
\edef\ppp{\GetProperty{##1}{##2}}
\typeout{Worker: ##1: ##1 : \ppp}
\IfSubStr{\ppp}{???}{}{%
"\ObjectLabel" -> %
\IfSubStr{\ppp}{:}{"\GetProperty{\GetProperty{\ppp}{rdf:type}}{rdfs:label}: \GetProperty{\ppp}{rdfs:label}"}{"\ppp"} %
%\GetProperty{##1}{##2}
[label="##2"];\\%
}
}
\MapPropertyList{rdf:type}{%
\xifinlist{\Second##1}{\typelist}{%
\edef\ObjectLabel{\GetProperty{\Second##1}{rdfs:label}: \GetProperty{\First##1}{rdfs:label}}%
%\ObjectLabel \& \Second##1\\}
\bgroup%
%\MapObjectList{\First##1}{}
\forcsvlist{\worker{\First##1}}{#2}%
\egroup
}%
{}%
}
\}
}
Because of some weird errors, I cannot do version which write to the file, so graphviz specification is simply printed to the document (really ugly, I know). It can be used in following way:
\ExportGraphviz{sec:sectioning,thm:theorem,eq:equation,thm:proposition,thm:proposition,thm:lemma}{doc:pageNo,doc:partOf,doc:hasParent}
First parameter is list of objects with given rdf:type which should be the exported, the second is list of properties. For some reason, on first run, when there is no aux file, it gives some errors, but after that, it should be OK
Resulting graph:

Also, it is easy using \MapPropertyList and \MapSubjectList to export data to some rdf serialization format, for example turtle and import them to some specialized rdf database, or visualization tool, and do many interesting things with them.
\refmacro in a macro of your own that writes the context of the reference to an external file (or saves it in an internal list). That would give the data "A uses B". Parsing/sorting that list would tell you also "B used by A". – Ethan Bolker May 14 '12 at 13:09TeXto write one, which I would if I needed it. But I don't, and don't have the time. Maybe one of the wizards who watch SE regularly can do it quickly. – Ethan Bolker May 14 '12 at 13:44reftexforemacsis great for tracking references across a large project provided you set up which file is the 'parent' and which ones are the 'children'. It comes bundled as part ofAUCTeX. – jon May 18 '12 at 14:36