Automated renaming of tags?

I have a research database with a particular set of heirarchical tags with a consistent naming scheme. Stuff comes into my global inbox from a variety of sources, generally having a range of other tags, most of which are predictable. It’s tedious to retag everything, so I’m wondering if there’s a way I can script the renaming of tags before/when I move this new material into my research db. I suspect it’s not sensible given that the research db has 200 tags and I’d need to allow for several possibilities for some of them. I can imagine having a regex search and replace get most things into the top level of the research tags, which would be half the battle.

Is there a better approach to this problem altogether? I know some people would say abandon tags. If I changed my research tags to groups, would that help (I don’t think I can use classify to put things into tag groups – do they work differently from regular groups?)?

Why do you actually want to rename tags before importing new stuff? An example might be useful.

Yes, this can be scripted with Applescript.

My research tags are based on Dewey Decimal classification, so a file may end up coming into my global inbox with a tag ‘epistemology’ that I would like to become ‘121 epistemology’ when it goes into my research db. Or at least, have some way of classifying the file as ‘121 epistemology’.

Any pointers to the best approach? I’ve googled a bit but not yet found anything I think I can adapt (given fairly limited AppleScript knowledge).

Create a tag epistemology, then via the Info Inspector add an alias 121 epistemology to it. A newly imported file with a Finder tag 121 epistemology will then get a DEVONthink tag epistemology.

Adding the necessary aliases could be scripted, I think.

1 Like

Writing a function of the pattern:

inputTag -> lookupTable -> outputTag

(where it sounds as if lookupTable might contain 200 or more key:value pairs)

would be:

  1. A nightmare in AppleScript
    • AppleScript records are fragile,
    • slow,
    • explode in error if we ask about a key which turns out not be in the record,
    • and want to be formatted on the page as a single enormously long line.
  2. Very straightforward in JavaScript (the second of the two osascript languages on macOS)

Do you have your table or rule-base of inputTag -> outputTag conversions in any form that you can show us ?

Is it just some specific sections of the Dewey outline ?

I suggest to let DEVONthink do the conversion via its aliases (see post above), this way there would be no need to run a script on each imported file.

I’ll leave this to you :slight_smile:

1 Like

let DEVONthink do the conversion via its aliases

Tho as rabbit holes and tarpits go, things like "Create a tag epistemology" * 200 plus sounds exceptionally deep …

As Yaks go it sounds unusually huge and hairy :slight_smile:

(and in terms of XKCD jokes, the punch-line may start to set in pretty early in the week …)

1 Like

I don’t think 200 plus aliases would be a problem but didn’t test.

Here are captures for @tonywatkins

  1. PDF in Finder

Finder

  1. Add an alias to a tag in DEVONthink’s Info Inspector

DEVONthink Info Inspector

  1. After importing the PDF

Imported file

This sounds like a good approach. Thanks!

I’ve only used aliases when merging existing tags (I’ve recently returned to DT after an absence of some years), so just to clarify: can an alias be used anywhere that the ‘master’ tag name is used – in searches, smart groups, smart rules, etc.?

I’ll try the alias approach for a few days and then think about the javascript approach. I’ve never scripted anything in javascript beyond a few very basic tweaks of web scripts. Thanks!

1 Like

Don’t know. Let’s ask @cgrunenberg

Aliases are only used by Wiki linking and to assign tags (no matter whether automatically or by the user).

1 Like

Ah, so using aliases won’t do much to help me automate this then.

We can write functions such as:

Term -> [possible Dewey matches]

[possible Dewey matches] -> tagWithChosenDeweyPrefix

deweyPrefix -> deweyName

which look things up in a JSON record of any size like:

{
  "100": "Philosophy & psychology",
  "101": "Theory of philosophy",
  "102": "Miscellany",
  "103": "Dictionaries & encyclopedias",
  "104": "[Unassigned]",
  "105": "Serial publications",
  "106": "Organizations & management",
  "107": "Education, research, related topics of philosophy",
  "108": "Groups of people",
  "109": "History & collected biography",
  "110": "Metaphysics",
  "111": "Ontology",
  "112": "No longer used—formerly Methodology",
  "113": "Cosmology (Philosophy of nature)",
  "114": "Space",
  "115": "Time",
  "116": "Change",
  "117": "Structure",
  "118": "Force and energy",
  "119": "Number and quantity",
  "120": "Epistemology, causation, and humankind",
  "121": "Epistemology (Theory of knowledge)",
  "122": "Causation",
  "123": "Determinism and indeterminism",
  "124": "Teleology",
  "125": "No longer used—formerly Infinity",
  "126": "The self",
  "127": "The unconscious & the subconscious",
  "128": "Humankind",
  "129": "Origin & destiny of individual souls",
  "130": "Parapsychology & occultism",
  "131": "Parapsychological and occult methods for achieving well-being, happiness, success",
  "132": "No longer used—formerly Mental derangements",
  "133": "Specific topics in parapsychology & occultism",
  "134": "No longer used—formerly Mesmerism & Clairvoyance",
  "135": "Dreams & mysteries",
  "136": "No longer used—formerly Mental characteristics",
  "137": "Divinatory graphology",
  "138": "Physiognomy",
  "139": "Phrenology",
  "140": "Specific philosophical schools and viewpoints",
  "141": "Idealism & related systems & doctrines",
  "142": "Critical philosophy",
  "143": "Bergsonism & intuitionism",
  "144": "Humanism & related systems & doctrines",
  "145": "Sensationalism",
  "146": "Naturalism & related systems & doctrines",
  "147": "Pantheism & related systems & doctrines",
  "148": "Dogmatism, eclecticism, liberalism, syncretism, & traditionalism",
  "149": "Other philosophical systems & doctrines",
  "150": "Psychology",
  "151": "No longer used—formerly Intellect",
  "152": "Sensory perception, movement, emotions, & physiological drives",
  "153": "Conscious mental processes & intelligence",
  "154": "Subconscious & altered states & processes",
  "155": "Differential & developmental psychology",
  "156": "Comparative psychology",
  "157": "No longer used—formerly Emotions",
  "158": "Applied psychology",
  "159": "No longer used—formerly Will",
  "160": "Philosophical logic",
  "161": "Induction",
  "162": "Deduction",
  "165": "Fallacies & sources of error",
  "166": "Syllogisms",
  "167": "Hypotheses",
  "168": "Argument & persuasion",
  "169": "Analogy",
  "170": "Ethics (Moral philosophy)",
  "171": "Ethical systems",
  "172": "Political ethics",
  "173": "Ethics of family relationships",
  "174": "Occupational ethics",
  "175": "Ethics of recreation, leisure, public performances, communication",
  "176": "Ethics of sex & reproduction",
  "177": "Ethics of social relations",
  "178": "Ethics of consumption",
  "179": "Other ethical norms",
  "180": "Ancient, medieval, eastern philosophy",
  "181": "Eastern philosophy",
  "182": "Pre-Socratic Greek philosophies",
  "183": "Sophistic, Socratic, related Greek philosophies",
  "184": "Platonic philosophy",
  "185": "Aristotelian philosophy",
  "186": "Skeptic & Neoplatonic philosophies",
  "187": "Epicurean philosophy",
  "188": "Stoic philosophy",
  "189": "Medieval Western philosophy",
  "190": "Modern Western & other noneastern philosophy",
  "191": "Philosophy of the United States and Canada",
  "192": "Philosophy of the British Isles",
  "193": "Philosophy of Germany and Austria",
  "194": "Philosophy of France",
  "195": "Philosophy of Italy",
  "196": "Philosophy of Spain and Portugal",
  "197": "Philosophy of Russia",
  "198": "Philosophy of Scandinavia & Finland",
  "199": "Philosophy in other geographic areas",
  "163–164": "Not assigned or no longer used"
}

and we can produce such records automatically, from a copy-paste of one or more sections of List of Dewey Decimal classes](https://en.wikipedia.org/wiki/List_of_Dewey_Decimal_classes) for example, by writing JS expressions this kind:

(() => {
    'use strict';

    // main :: IO ()
    const main = () => {
        const
            dictPartialDewey = lines(deweySample)
            .reduce(
                (sofar, line) => {
                    const parts = words(line);
                    return Object.assign(
                        sofar, {
                            [parts[0]]: unwords(
                                parts.slice(1)
                            )
                        }
                    );
                }, {} // Seed value. (Empty dictionary)
            );
        return JSON.stringify(
            dictPartialDewey,
            null, 2
        );
    };

    const deweySample = `100 Philosophy
100 Philosophy & psychology
101 Theory of philosophy
102 Miscellany
103 Dictionaries & encyclopedias
104 [Unassigned]
105 Serial publications
106 Organizations & management
107 Education, research, related topics of philosophy
108 Groups of people
109 History & collected biography
110 Metaphysics
110 Metaphysics
111 Ontology
112 No longer used—formerly Methodology
113 Cosmology (Philosophy of nature)
114 Space
115 Time
116 Change
117 Structure
118 Force and energy
119 Number and quantity
120 Epistemology
120 Epistemology, causation, and humankind
121 Epistemology (Theory of knowledge)
122 Causation
123 Determinism and indeterminism
124 Teleology
125 No longer used—formerly Infinity
126 The self
127 The unconscious & the subconscious
128 Humankind
129 Origin & destiny of individual souls
130 Parapsychology & occultism
130 Parapsychology & occultism
131 Parapsychological and occult methods for achieving well-being, happiness, success
132 No longer used—formerly Mental derangements
133 Specific topics in parapsychology & occultism
134 No longer used—formerly Mesmerism & Clairvoyance
135 Dreams & mysteries
136 No longer used—formerly Mental characteristics
137 Divinatory graphology
138 Physiognomy
139 Phrenology
140 Philosophical schools of thought
140 Specific philosophical schools and viewpoints
141 Idealism & related systems & doctrines
142 Critical philosophy
143 Bergsonism & intuitionism
144 Humanism & related systems & doctrines
145 Sensationalism
146 Naturalism & related systems & doctrines
147 Pantheism & related systems & doctrines
148 Dogmatism, eclecticism, liberalism, syncretism, & traditionalism
149 Other philosophical systems & doctrines
150 Psychology
150 Psychology
151 No longer used—formerly Intellect
152 Sensory perception, movement, emotions, & physiological drives
153 Conscious mental processes & intelligence
154 Subconscious & altered states & processes
155 Differential & developmental psychology
156 Comparative psychology
157 No longer used—formerly Emotions
158 Applied psychology
159 No longer used—formerly Will
160 Philosophical logic
160 Philosophical logic
161 Induction
162 Deduction
163–164 Not assigned or no longer used
165 Fallacies & sources of error
166 Syllogisms
167 Hypotheses
168 Argument & persuasion
169 Analogy
170 Ethics
170 Ethics (Moral philosophy)
171 Ethical systems
172 Political ethics
173 Ethics of family relationships
174 Occupational ethics
175 Ethics of recreation, leisure, public performances, communication
176 Ethics of sex & reproduction
177 Ethics of social relations
178 Ethics of consumption
179 Other ethical norms
180 Ancient, medieval, & Eastern philosophy
180 Ancient, medieval, eastern philosophy
181 Eastern philosophy
182 Pre-Socratic Greek philosophies
183 Sophistic, Socratic, related Greek philosophies
184 Platonic philosophy
185 Aristotelian philosophy
186 Skeptic & Neoplatonic philosophies
187 Epicurean philosophy
188 Stoic philosophy
189 Medieval Western philosophy
190 Modern Western philosophy (19th-century, 20th-century)
190 Modern Western & other noneastern philosophy
191 Philosophy of the United States and Canada
192 Philosophy of the British Isles
193 Philosophy of Germany and Austria
194 Philosophy of France
195 Philosophy of Italy
196 Philosophy of Spain and Portugal
197 Philosophy of Russia
198 Philosophy of Scandinavia & Finland
199 Philosophy in other geographic areas`;

    // --------------------- GENERIC ---------------------

    // lines :: String -> [String]
    const lines = s =>
        // A list of strings derived from a single
        // string delimited by newline and or CR.
        0 < s.length ? (
            s.split(/[\r\n]+/)
        ) : [];

    // unwords :: [String] -> String
    const unwords = xs =>
        // A space-separated string derived
        // from a list of words.
        xs.join(' ');

    // words :: String -> [String]
    const words = s =>
        // List of space-delimited sub-strings.
        s.split(/\s+/);

    return main();
})();

I’m out of my depth here, and I don’t have time to start getting into javascript. Thanks though – it’s something to bear in mind for the future.

1 Like

Either I misunderstood what you want to do or you didn’t understand how aliases work.

All you have to do is to add an alias to every tag (this can be scripted). Afterwards you can use the tag like you would use any other tag.

You just can’t use the aliases in Smart Groups etc. - but that would be the exact same if you renamed a tag manually after import to match your tag system.

Or am I missing something?

I’m sure it’s me not understanding! I’ve recently come back to DTPO after so long that I don’t really remember how I used it before, especially because so much has changed for the better.

What I was hoping to do was take a file from my global inbox, say with a tag of ‘epistemology’ to use my previous example and then have that tag become ‘121 epistemology’ when moving it into my research db, as then I could automate it going into the right group.

In the last half an hour it’s occurred to me that I might be better not excluding groups from tagging (as I have been doing). Then I could have groups (+group tags) for the Dewey classifications I need (i.e have a group ‘121 epistemology’ rather than just a tag). Then I think I could use the classify function to get this new file into the relevant group, picking up the appropriate ‘121 epistemology’ tag as a consequence. Then I could simply ignore the old tags, which will all begin with letters rather than digits. I could probably also create a simple script to remove these old tags periodically if they get in the way.

Part of my problem here is that I’m trying to figure out whole new workflows to make good use of DT3, while trying to re-order my research materials in the process, but it’s such a Swiss Army knife that there are many tools I don’t know how to make good use of yet and many competing ideas about what the best approach is.

I appreciate your attempts to help me in my muddle!

1 Like

Afaik, the classification does not consider tags