sorry if this has been discussed somewhere (I have checked forum and didn´t find precedence); and sorry if it meshes two things that might have somewhat different status (for the ‘naíve me’ this appears as one issue-context).
I would like to
1 - style all MD-files w/in a folder and/or DB with help of a specific CSS. it seems to me
a) this can not be done per se;
b) would be doable if there is a way to automate the inclusion of the css-instruction at the top of any MD-file located in ‘X’
2 - insert a TOC ({{TOC}} ) in the same way at the top of given MD-files (in location ‘X’) – either on Top, or – even better – by default after the first h1-tag.
(just in case you wonder: TOC does not only produce the TOC where I´d want it instead of the DT-pane for content-structure (right side-pane), but also a cleaner version for my purposes… which is, why I need it )
questions:
– can this be done? (if so can you point me a way? )
– has this already been done (is there a resource for that), or have I overlooked an obvious resource for this within DT?
You can define a css file in the preferences. I’m sure it’s described in more detail in the documentation And md styling with css has been discussed in the forum, too.
If you select a global stylesheet in the Preferences > Media > Markdown, it will apply to all Markdown files. This may - or may not - be what you want to do.
If not, it is possible to script something. Here is a teaching edition example - noting you’ll have to replace the item link with the link of the stylesheet you want to use…
property stylesheet : "<link rel=\"stylesheet\" href=\"x-devonthink-item://6C8A682B-8B28-4DDB-84AC-D78C26577019\" />" -- The item link is from the CSS file. This is one approach but allows for some flexibility in where the stylesheet is located.
set ot to AppleScript's text item delimiters -- Cache the default AppleScript text item delimiters
tell application id "DNtp"
repeat with thisRecord in (selected records) -- Process any selected records
if (type of thisRecord as string = "markdown") or (type of thisRecord as string = "text") then -- Check the file type
set src to plain text of thisRecord -- Get the plain text of the file to process
repeat with incr from 1 to (count paragraphs of src) -- Process the paragraphs looking for the first Markdown header
if paragraph incr of src begins with "# " then
-- The section here is required in this case as empty paragraphs, i.e., returns, aren't preserved when converted to strings
set AppleScript's text item delimiters to return -- Change the delimiters to a return
set bef to (paragraphs 1 thru incr) of src -- Get the current line and the ones preceding it
set bef to text items of bef as string
set aft to (paragraphs (incr + 1) thru -1) of src -- Get the next line and the ones following it
set aft to (text items of aft as string)
-- Stringing the text of the file back together and replacing the text.
set plain text of thisRecord to (stylesheet & return & return & bef & return & return & "{{TOC}} " & return & return & aft)
exit repeat -- Stop looping as we only want to introduce the {{TOC}} once.
end if
end repeat
end if
end repeat
set AppleScript's text item delimiters to ot -- Reset the delimiters to the original state
end tell
The script can be saved in the ~/Library/Application Scripts/com.devon-technologies.think3/Menu directory for use as needed.
thx a load for these swift and helpful comments to all!
@chrillek: thx for reaction. I was indeed aware of the global setting, and was asking for more granular options (– as for rationale: I would like to treat my text + write up sketches differently than, say, my archived diary and journal entries)
@cgrunenberg: that is a helpful hint in general. in my case, I am dealing with MD-files regularly imported (indexed) from another app
@BLUEFROG: thx for that amazing shoot. I´ll try to dive into it, being not too script-literate. but I am always reminded that one can just do amazing things w/ scripting. so, appreciate the lead and will try to wander off into the wilderness…
… will also try to extend this to a solution on {{TOC}}-insertion. meanwhile any additional hints on this one by the more initiated still welcome + appreciated!
I tried several routes (and restarts):
1 - via script-menu, triggering it on the (test-)MD-file as well as its parent folder
2 - same via smart rule (including the ‘on performSmartRule(…) – end performSmartRule’ bracketing
in both case… well… nothing happened. no error message. no indication of processing. but also no result (neither TOC-insert, nor the stylesheet-referencing)
I do not want to take up free time of anyone.
so I comforted myself w/ going back to the global CSS-toggle-option and making my peace with it. (as to TOC … I can/will insert it by hand, when really needed)
– just thought to leave a feedback / trace here. for others.
… and for documentation of my so-so-relation to scripts
I am no Markdown-expert. but it seems a ‘simple’(?) MD file generated as output from Diarly. it uses
a) very basic /standard markup (as far as I can tell; i.e. headings, italics/bold, highlight, img; links, hr… not more)
b) the only remarkable thing seems ‘******’ for ‘hr’; and that it uses for attachments… but that also is standard, I think
c) …actually I was checking with minimal versions, only containing some h1 and h2 lines … still same problem
also: the smart rule I constructed also found some MD-files from earlier ‘Notebooks’-exports (the software by Alfons Schmid). very basic entries - here: same problem. nothing happens. neither w/ menu script nor w/ smart rule…
Stupid question: Did you adjust the link to the style sheet at the top of the script to the one you want to use? 2nd question: Did anything appear in DT’s log window?
@chrillek: no question is stupid in cases where someone interacts ‘stupidly’ w/ scripting, as is the case for me so good + thx for double checking!
answer #1: yes! I did. meanwhile I have some feeling for what to look out for / attend to – even if it´s not very well-founded in real scripting-knowledge.
answer #2: example of me being somewhat stupid nevertheless. of course log-files is something I should have thought of! – result: no entry whatsoever; just checked again. then it gives a log-entry for my smart rule… probably done something wrong there… but then, it seems the script it self is not working anyways…
on performSmartRule(theRecords)
property stylesheet : "<link rel=\"stylesheet\" href=\"x-devonthink-item://6C8A682B-8B28-4DDB-84AC-D78C26577019\" />" -- The item link is from the CSS file. This is one approach but allows for some flexibility in where the stylesheet is located.
set ot to AppleScript's text item delimiters -- Cache the default AppleScript text item delimiters
tell application id "DNtp"
repeat with thisRecord in (selected records) -- Process any selected records
if (type of thisRecord as string = "markdown") or (type of thisRecord as string = "text") then -- Check the file type
set src to plain text of thisRecord -- Get the plain text of the file to process
repeat with incr from 1 to (count paragraphs of src) -- Process the paragraphs looking for the first Markdown header
if paragraph incr of src begins with "# " then
-- The section here is required in this case as empty paragraphs, i.e., returns, aren't preserved when converted to strings
set AppleScript's text item delimiters to return -- Change the delimiters to a return
set bef to (paragraphs 1 thru incr) of src -- Get the current line and the ones preceding it
set bef to text items of bef as string
set aft to (paragraphs (incr + 1) thru -1) of src -- Get the next line and the ones following it
set aft to (text items of aft as string)
-- Stringing the text of the file back together and replacing the text.
set plain text of thisRecord to (stylesheet & return & return & bef & return & return & "{{TOC}} " & return & return & aft)
exit repeat -- Stop looping as we only want to introduce the {{TOC}} once.
end if
end repeat
end if
end repeat
set AppleScript's text item delimiters to ot -- Reset the delimiters to the original state
end tell
end performSmartRule
In addition to what @pete31 said, I’d leave out the whole smartrule thingy. That’s a bit pointless here, I think.
To ease debugging, you might want to run the script in ScriptEditor and check the output that’s generated there.
I have the impression that the plain text of a markdown file has no paragraphs. At least not in the MD file I’m experimenting with (which is long-ish and certainly does have paragraphs).
I propose an alternate version of the script written in JavaScript.
(() => {
/* self executing function */
let app = Application("DEVONthink 3");
let stylesheet = `<link rel="stylesheet" href="x-devonthink-item://0841105D-70B7-4518-8E2C-68E25CF8FC38" />`;
app.selectedRecords().forEach(r => {
let src = r.plainText();
let toc = "";
if (new RegExp("^# ","m").test(src)) {
toc = "{{TOC}} ";
}
r.plainText = `${stylesheet}\n\n\n\n${toc}\n\n${src}`
})
})()
What it does (here, with one example file): Add the <link…> to the CSS at the top line, add four blank lines after that, adds {{TOC}} on a line by itself, two more blank lines. The original MD file follows.
I am ‘blushed’ by the brain-/scriptpowers going into this, and being shared.
I will have to put myself deeper into all this, getting hands dirty. for now this finds me w/ a lack of technical understanding and currently low bandwith. so,
@chrillek: thx a lot! I have also seen the other debates/hints on using JS. but in the end, I can´t even make this ‘fire’ trigger (I have tried putting it into the folder, one time as .scpt-file; one time as .js-file. the first desnt´t do anything; the js doesn´t appear at all; and trying reconstructing the smart rule way also led me nowhere…)
I guess, I will have to return later with some more breath.
but meanwhile big ‘thank you all!’ – and I hope this als might give others ideas / hints…
best!
ps: meanwhile I´ll settle w/ glbal css-toggle. there are worse work-arounds
Whatever that means. You can copy& paste it into script editor (selecting JavaScript in the tool bar), select a record in DT am then run the script in script editor. If it does what you want, save it (from script editor) in DT’s script location, whatever subfolder seems appropriate.
Then you can select the records to modify in DT and run the script from the script menu in DT. From your post, I have no idea what you were doing at all. Beware though: in this form, it can’t be used in a smart rule!