The script included below creates a markdown table in a Safari web page that supports markdown (typically a forum). The first row of the table is a header and is not included in the number of rows specified by the user. The second row of the table allows the user to specify whether the column is left-aligned (:—), center-aligned (:—:), or right-aligned (—:). The number of dashes have no significance, although there should be at least three of them.
The following is an example of a simple table. The table itself is left aligned, and there’s no easy way to change this.
First Name |
Last Name |
Status |
Peavine |
Peabody |
member |
Nigel |
Garvey |
moderator |
Shane |
Stanley |
developer |
The script:
--revised 2024.07.29
display dialog "Enter the number of columns, a space, and the number of rows. Then select whether the columns should be left or center aligned." buttons {"Cancel", "Center", "Left"} with title "Markdown Table Generator" default button 3 default answer "3 3"
set {columnAlignment, columnAndRowCount} to {button returned, text returned} of result
set text item delimiters to {" "}
try
set columnCount to (text item 1 of columnAndRowCount) as integer
set rowCount to (text item 2 of columnAndRowCount) as integer
on error
display dialog "The entered data could not be processed" buttons {"OK"} cancel button 1 default button 1
end try
set text item delimiters to {""}
set {dataRow, formatRow} to {"|", "|"}
if columnAlignment is "Left" then
repeat columnCount times
set dataRow to dataRow & " |"
set formatRow to formatRow & " :--- |"
end repeat
else
repeat columnCount times
set dataRow to dataRow & " |"
set formatRow to formatRow & " :---: |"
end repeat
end if
set dataRows to ""
repeat rowCount times
set dataRows to dataRows & dataRow & linefeed
end repeat
set theTable to dataRow & linefeed & formatRow & linefeed & dataRows
set the clipboard to theTable
tell application "System Events" to tell process "Safari"
try
set frontmost to true
delay 0.3 --may not be needed
click menu item "Paste" of menu "Edit" of menu bar 1
end try
end tell
3 Likes
Pretty handy.
I don’t use markdown tables very often but sometimes I do when capturing part of a wikipedia page in devonthink… typically to lay out one of the information boxes, or occasionally when capturing some sports statistics.
I often forget the syntax as I do that infrequently so this should help.
As an aside, while it doesn’t seem to work on this site, you can add CSS styles to markdown and that includes centering a table.
Putting this at the top of a devonthink markdown document would cause any table to be centred horizontally on the page. It should work in most (non-online) markdown environments.
<style>
table {
margin-left: auto;
margin-right: auto;
}
</style>
1 Like
Nice one, @peavine.
Here for my own amusement on a Sunday morning — and in the spirit of Code Exchange, of course — is some tinkering with your code. Apart from a slight tightening up of the input checks, I wouldn’t claim it to be any better than your original.
set {text returned:columnsAndRows, button returned:theAlignment} to ¬
(display dialog "Enter the number of columns, a space, and the number of rows. Then select whether the columns should be left or center aligned." buttons {"Cancel", "Center", "Left"} with title "Markdown Table Generator" default button 3 default answer "3 3")
set {astid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {space}}
set {columnsAndRows, AppleScript's text item delimiters} to {columnsAndRows's text items, astid}
try
set {columnCount, rowCount} to columnsAndRows
if (((count columnsAndRows) > 2) or (1 > columnCount) or (0 > rowCount)) then error
on error
display dialog "The entered data could not be processed" buttons {"OK"} cancel button 1 default button 1
end try
set rowTemplate to {"|"}
repeat columnCount times
set rowTemplate's end to "|"
end repeat
set aHeaderOrRow to join(rowTemplate, " ")
set theFormatter to join(rowTemplate, {" :---: ", " :--- "}'s item (((theAlignment is "Left") as integer) + 1))
set theRows to {aHeaderOrRow, theFormatter}
repeat rowCount times
set theRows's end to aHeaderOrRow
end repeat
set theTable to join(theRows, linefeed)
set the clipboard to theTable
tell application "System Events" to tell process "Safari"
try
set frontmost to true
delay 0.3 --may not be needed
click menu item "Paste" of menu "Edit" of menu bar 1
end try
end tell
on join(lst, delim)
set {astid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, delim}
set {txt, AppleScript's text item delimiters} to {lst as text, astid}
return txt
end join
1 Like
Here is an extension of @peavine’s script.
If you feed it some tabular data, then it should output the final table.
As it basically just pipes the data into the field spots, it must have the requisite number of tabs, even if there isn’t any data for a particular record/field. There are probably ways to deal with this gracefully but this version of the script doesn’t attempt that.
I included two examples of data. Uncomment the second one to test it out. For actual use, I’ll probably set it up to get the data from the clipboard and then calculate the row and column count from that.
use scripting additions
display dialog "Enter the number of columns, a space, and the number of rows. Then select whether the columns should be left or center aligned." buttons {"Cancel", "Center", "Left"} with title "Markdown Table Generator" default button 3 default answer "2 5"
set {columnAlignment, columnAndRowCount} to {button returned, text returned} of result
set text item delimiters to {" "}
try
set columnCount to (text item 1 of columnAndRowCount) as integer
set rowCount to (text item 2 of columnAndRowCount) as integer
on error
display dialog "The entered data could not be processed" buttons {"OK"} cancel button 1 default button 1
end try
set text item delimiters to {""}
set {dataRow, formatRow} to {"|", "|"}
set {centr, lef} to {" :---: |", " :--- |"}
-- set default alignment
if columnAlignment is "Left" then
set colAlign to lef
else -- is centred
set colAlign to centr
end if
-- use '•' as a field token
repeat columnCount times
set dataRow to dataRow & " • |"
set formatRow to formatRow & colAlign
end repeat
-- append rows
set dataRows to ""
repeat rowCount times
set dataRows to dataRows & dataRow & linefeed
end repeat
set theTable to dataRow & linefeed & formatRow & linefeed & dataRows -- prepend headings
-- set the clipboard to theTable
set tableTop to dataRow & linefeed & formatRow -- headings and alignment rows
set tableStructure to dataRows -- data rows
-- data examples, tab-separated
-- example 1: '2 5'
set tabData to "Case Opinions
Majority Powell, joined by Burger
Stewart, Blackmun, Stevens
Concurrence Burger
Dissent White, joined by Brennan, Marshall
Dissent Rehnquist"
-- example 2: '6 10'
(*
set tabData to "Rk Player Tm Car Yds TD
1 Derrick Henry* TEN 280 1167 12
2 Christian McCaffrey*+ SFO 272 1459 14
3 Rachaad White TAM 272 990 6
4 Travis Etienne JAX 267 1008 11
5 Joe Mixon CIN 257 1034 9
6 Najee Harris PIT 255 1035 8
7 Tony Pollard DAL 252 1005 6
8 Saquon Barkley NYG 247 962 6
9 Chuba Hubbard CAR 238 902 5
10 James Cook* BUF 237 1122 2"
*)
-- separate heading from data
set text item delimiters to linefeed
set headData to paragraph 1 of tabData
set bodyData to rest of paragraphs of tabData as text
-- split into lists of field data
set text item delimiters to {linefeed, tab}
set bd to text items of bodyData
set hd to text items of headData
set text item delimiters to "•"
set blocks to ""
set heads to ""
-- replace bullets with field data
set tsd to text items of tableStructure
repeat with di from 1 to ((count of tsd) - 1)
set blocks to blocks & item di of tsd & item di of bd
end repeat
set blocks to blocks & " |"
set ttd to text items of tableTop
repeat with hi from 1 to ((count of ttd) - 1)
set heads to heads & item hi of ttd & item hi of hd
end repeat
-- stitch parts together and output
set finalTable to heads & last item of ttd & linefeed & blocks
set the clipboard to finalTable
finalTable
The two outputs should like something like these:
Case Opinions |
|
Majority |
Powell, joined by Burger |
|
Stewart, Blackmun, Stevens |
Concurrence |
Burger |
Dissent |
White, joined by Brennan, Marshall |
Dissent |
Rehnquist |
Rk |
Player |
Tm |
Car |
Yds |
TD |
1 |
Derrick Henry* |
TEN |
280 |
1167 |
12 |
2 |
Christian McCaffrey*+ |
SFO |
272 |
1459 |
14 |
3 |
Rachaad White |
TAM |
272 |
990 |
6 |
4 |
Travis Etienne |
JAX |
267 |
1008 |
11 |
5 |
Joe Mixon |
CIN |
257 |
1034 |
9 |
6 |
Najee Harris |
PIT |
255 |
1035 |
8 |
7 |
Tony Pollard |
DAL |
252 |
1005 |
6 |
8 |
Saquon Barkley |
NYG |
247 |
962 |
6 |
9 |
Chuba Hubbard |
CAR |
238 |
902 |
5 |
10 |
James Cook* |
BUF |
237 |
1122 |
2 |
1 Like