4
$\begingroup$

I' m trying to set up a gizmo to manage the large notebooks collection, in my Mathematica workspace. The main idea is to embed indexing metadata in each notebook and manage them by means of function defined in init.m . It should look like some sort of CMS, or an advanced snippet manager.

The problem (and this question ...) is: how can I encapsulate metadata in a notebook, keeping them both human readable and easily parsable ?.

To show my efforts to solve the problem, I give an answer below, but, obviously, it remains largely unsolved, and that is the reason why this question exists.

$\endgroup$
4
$\begingroup$

Here three approachs:

1. Using comments like (* metadata *) written as plain text directly in the notebook's file.

Pros: Human readable. Simple to manage. Readable from other application. If in XML format, simply to validate against a DTD.

Cons: Unpredictable behaviour (well, ... a behaviour that I can't understand): sometime I have seen comments, all of a sudden, to be stripped away and I have been incapable even to replicate the event for further studying, except when the notebook gets corrupted for other reasons and the Open , Parse and load ... option is used.

2. Setting TaggingRules for the entire notebook, using XML string.

Pros: Mathematica is surely respectful to Tagging Rules. By means of ImportString, metadata can be validated against a DTD.

Cons: Beyond toy cases, no user friendly, and requires complex code to be presented, to add or remove field, etc.

3. Using dedicated cells.

Pro: Human readable. Easily managed from within the notebook.

Cons: Tricky to manage from outside the notebook.

Example:

A program cell, tagged "metadata" contains

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tableHeader
[
<!ELEMENT tableHeader (record)+>
<!ELEMENT record (fieldA, fieldB)>
<!ELEMENT fieldA (#PCDATA)>
<!ELEMENT fieldB (#PCDATA)>
]>
<tableHeader>
    <record>
        <fieldA>record 1 field 1</fieldA>
        <fieldB>record 1 field 2</fieldB>
    </record>
</tableHeader>

and this code makes use of it:

Quiet[Remove[findMetadata]];
findMetadata[cell_] := Module[{metadata},
   metadata = CellTags /. Options @ cell;
   Return @ If[TrueQ[metadata == "metadata"], cell, Null];
   ];
SetAttributes[findMetadata, Listable];
metadata = (findMetadata @ NotebookGet[][[1]])[[1, 1]];
title = First @
   ImportString[metadata, {"XML", "CDATA"}, "ValidateAgainstDTD" -> True];
SetOptions[EvaluationNotebook[], DockedCells -> Cell[title, "Title"]];
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.