As in (ignoring other associations) third column (and thus up to Nth column) ?
This one uses a fixed-width for field 1 of the table including the . leaders.
Field 2 is flexible but must begin with ‘Working’ or ‘Meeting’.
-Chris
Make Two Column Table with . Leader (Perl) v1.00.kmmacros (7.3 KB)
If you can accept having SPACE filled text, then the simple bash column
command will do.
But if you want exactly what you have posted, then you will need a couple of RegEx Search/Replace Actions to replaces the SPACES with dots. Maybe one of the Shell Script gurus will know how to make the bash column
command use a different fill character.
Example Output
Below is just an example written in response to your request. You will need to use as an example and/or change to meet your workflow automation needs.
Please let us know if it meets your needs.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MACRO: Create Text Table from TAB Delimited Text [Example]
-~~~ VER: 1.0 2021-02-10 ~~~
Requires: KM 8.2.4+ macOS 10.11 (El Capitan)+
(Macro was written & tested using KM 9.0+ on macOS 10.14.5 (Mojave))
DOWNLOAD Macro File:
Create Text Table from TAB Delimited Text [Example].kmmacros
Note: This Macro was uploaded in a DISABLED state. You must enable before it can be triggered.
ReleaseNotes
Author.@JMichaelTX -- based on script by @ccstone
PURPOSE:
- Create Text Table from TAB Delimited Text [Example]
HOW TO USE
- First, make sure you have followed instructions in the Macro Setup below.
- Change Source String to your string.
- Do NOT use any TAB characters
- You may have one or more spaces between the last am/pm and the description (Working/Meeting).
- Trigger this macro.
MACRO SETUP
- Carefully review the Release Notes and the Macro Actions
- Make sure you understand what the Macro will do.
- You are responsible for running the Macro, not me. ??
.
.
Make These Changes to this Macro
- Assign a Trigger to this macro.
- Move this macro to a Macro Group that is only Active when you need this Macro.
- ENABLE this Macro, and the Macro Group it is in.
.
- REVIEW/CHANGE THE FOLLOWING MACRO ACTIONS:
(all shown in the magenta color)- SET Source String
- Do NOT use any TAB characters
- You may have one or more spaces between the last am/pm and the description (Working/Meeting).
- SET Source String
REQUIRES:
- KM 9.0+ (may work in KM 8.2+ in some cases)
- macOS 10.11.6 (El Capitan)+
TAGS: @TextTable @Regex @ShellScript @Example
USER SETTINGS:
- Any Action in magenta color is designed to be changed by end-user
ACTION COLOR CODES
- To facilitate the reading, customizing, and maintenance of this macro,
key Actions are colored as follows: - GREEN -- Key Comments designed to highlight main sections of macro
- MAGENTA -- Actions designed to be customized by user
- YELLOW -- Primary Actions (usually the main purpose of the macro)
- ORANGE -- Actions that permanently destroy Variables or Clipboards,
OR IF/THEN and PAUSE Actions
==USE AT YOUR OWN RISK==
- While I have given this a modest amount of testing, and to the best of my knowledge will do no harm, I cannot guarantee it.
- If you have any doubts or questions:
- Ask first
- Turn on the KM Debugger from the KM Status Menu, and step through the macro, making sure you understand what it is doing with each Action.
Depends.
Do you still want the Working and Meeting to line up and let the extra stuff after that trail off to various lengths? If so, just add (.*)
to the end of the regular expression and add the 3rd captured group to the end of the output, i.e.,
#!/usr/bin/python3
import re
import fileinput
entry = re.compile(r'^(.+)(Meeting|Working)(.*)$')
for line in fileinput.input():
m = entry.match(line)
if m:
print(f'{m.group(1):.<21s} {m.group(2)}{m.group(3)}')
That turns
8 - 10am Working, saw video of people with Cat filter on on video
7 - 9am Working
9 - 11am Meeting with people I hate
11 - 11:30am Meeting
11:30am - 12:30pm Meeting
12:30pm - 1pm Working
2 - 5pm Working
into
8 - 10am ............ Working, saw video of people with Cat filter on on video
7 - 9am ............. Working
9 - 11am ............ Meeting with people I hate
11 - 11:30am ........ Meeting
11:30am - 12:30pm ... Meeting
12:30pm - 1pm ....... Working
2 - 5pm ............. Working
If that's not the kind of output you want, the answer will probably be more complicated.
(If you put .*
after Working and Meeting in the second capture group, there's no need for a third group, and the print
line could go back to what it was. I added the third group because I thought it made the code clearer. Now I'm not sure there's any value in it.)
It was a good question and harvested well, not only because it clearly showed:
- a sample of input,
- and a sample of target output
but also, I think, because it touches on some very general and recognisable problems that everyone bumps into:
- splitting each of several rows into column cells
- specifying alignment or centering for each column
- getting the minimum width of each column from column contents
- choosing a (possibly non-space) padding character for the justification or centering
- specifying any additional whitespace padding
I wonder if it would be useful to have a (custom or buillt-in) KM action for tabulation of delimited rows ?
"Emplace".
Okay, I'll try again...
-Chris
--------------------------------------------------------
# Auth: Christopher Stone
# dCre: 2021/02/12 06:10
# dMod: 2021/02/12 06:37
# Appl: AppleScript
# Task: Create a Fixed-Width Table with Data 03.
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @Create, @Fixed_Width @Table
--------------------------------------------------------
set theData to paragraphs 2 thru -2 of "
7 - 9am Working
9 - 11am Meeting
11 - 11:30am Meeting
11:30am - 12:30pm Meeting
12:30pm - 1pm Working
2 - 5pm Working
"
property tableWidth : 29
property dotPad : "........................................"
set AppleScript's text item delimiters to {" "}
repeat with i in theData
tell i to set contents of i to (its text items 1 thru -2 as text) & space & (text 1 thru (tableWidth - 2 - ((length of (text items 1 thru -2 of i as text)) + (length of (last text item of i)))) of dotPad) & space & (its last text item)
end repeat
set AppleScript's text item delimiters to linefeed
return theData as text
--------------------------------------------------------
If I set the shell script action to display text in a window, everything looks great:
However, if I save the script result to a variable and then use the Display Text in a Window action, I get:
If I paste the misaligned output here, it looks fine:
Local__Test: [test1]
--------------------------------------------------------------------
Local__LongTestVariableName: [test2]
--------------------------------------------------------------------
So what gives?
Change the font of the display text action to a monospaced font.
I typically use Menlo 14.
Nice! Thanks Chris!
Here's an evolution of the same concept:
Align Text as Columns.kmmacros (23 KB)
Example input:
Instrument: Name: Wife: Years Married
Rhythm Guitar: John: Yoko: 69-80
Bass: Paul: Linda: 67-98
Lead Guitar: George: Pattie: 66-77
Drums: Ringo: Maureen: 65-75
Output:
Instrument Name Wife Years Married
Rhythm Guitar John Yoko 69-80
Bass Paul Linda 67-98
Lead Guitar George Pattie 66-77
Drums Ringo Maureen 65-75
Options:
- Additional Separation Spaces
Set to 0
, a single space will separate columns. Any positive value will add addional spaces.
- Delimiter
Set the delimiter that will differentiate column bounds.
Thanks @noisneil for creating this macro. I don't need it right now, but I know I will need it one day.
ChrisQ
No worries. Here's another approach using tabs instead of spaces.
One thing I've noticed with the tab version is that if you paste it into TextEdit, for example, and then select a monospaced font, it's perfect.
However, if you write it to a file as styled text with the same font, the tabs occasionally come out a bit squiffy.
Any ideas why that might be?
A lot of shell utilities are going to expect monospaced fonts.
I'm using Menlo, which is monospaced.
No idea how this Keyboard Maestro Execute JavaScript for Automation action compares in terms of speed.
Monospaced columns (as defined by delimiter) separated by given gap.kmmacros (5.3 KB)
Expand disclosure triangle to view JS source
(() => {
"use strict";
// Columns of Text (as defined by given Delimiter),
// padded to even width, and separated by given Gap.
// Rob Trew @2023
// Ver 0.01
const main = () => {
const
kmVar = kmValue(kmInstance()),
[txt, delim, gap] = ["Text", "Delimiter", "Gap"]
.map(k => kmVar(`local_${k}`)),
rows = lines(txt).map(
row => row.split(delim).map(k => k.trim())
),
n = Math.max(...rows.map(row => row.length)),
fullRows = rows.map(row => {
const m = row.length;
return n === m
? row
: row.concat(
Array.from(
{length: n - m},
() => ""
)
);
});
return transpose(
transpose(fullRows).map(column => {
const
w = Math.max(
...column.map(cell => cell.length)
);
return column.map(
cell => cell.padEnd(w, " ")
);
})
)
.map(row => row.join(gap))
.join("\n");
};
// ---------------- KEYBOARD MAESTRO -----------------
// kmValue :: KM Instance -> String -> IO String
const kmValue = instance =>
k => Application("Keyboard Maestro Engine")
.getvariable(k, {instance});
// kmInstance :: () -> IO String
const kmInstance = () =>
ObjC.unwrap(
$.NSProcessInfo.processInfo.environment
.objectForKey("KMINSTANCE")
) || "";
// --------------------- GENERIC ---------------------
// lines :: String -> [String]
const lines = s =>
// A list of strings derived from a single string
// which is delimited by \n or by \r\n or \r.
0 < s.length
? s.split(/\r\n|\n|\r/u)
: [];
// transpose :: [[a]] -> [[a]]
const transpose = rows =>
// The columns of the input transposed
// into new rows.
// Simpler version of transpose, assuming input
// rows of even length.
0 < rows.length
? rows[0].map(
(_, i) => rows.flatMap(v => v[i])
)
: [];
// MAIN ---
return main();
})();