Source: S38 Stato d’anima 1900. Film 1732191, Page 458 of 872 accessed 7 Jul 2024
Source: S38 Chiesa cattolica San Pietro Apostolo Registri ecclesiastici di Rovinaglia (Parma), 1597-1932 Publication: Name: Laboratorio di Ecologia dell'Università di Parma; Location: Pontassieve, Italy; Date: 1977;
What might I do for a Keyboard macro to remove the "Source: S38" (given that this is not a static entry, but it might be S1, S2, S3, S_infinitum) to end up with the lines reversed and a result of:
Chiesa cattolica San Pietro Apostolo Registri ecclesiastici di Rovinaglia (Parma), 1597-1932 Publication: Name: Laboratorio di Ecologia dell'Università di Parma; Location: Pontassieve, Italy; Date: 1977; Stato d’anima 1900. Film 1732191, Page 458 of 872 accessed 7 Jul 2024
I'm assuming highlight the text, copying into a named clipboard or similar, making some adjustments and pasting the outcome. It's the fact that I'm not searching for a specific "S" value that I don't seem to have figured out.
Thanks!
Danita
PS this is a bit overly simplified, because here we have just two lines, but I might have multiple lines where there are multiple S values and duplicate S values, but I think maybe it's easier to start with a single possibility and then move from there.
return (() => {
"use strict";
const main = () => {
const rgxSourceRef = /^([\- ]*Source: S\d+)(.*)$/u;
return groupOnKey(fst)(
lines(kmvar.local_Source)
.flatMap(s => {
const m = s.match(rgxSourceRef);
return m
? [[m[1], m[2].trim()]]
: [];
})
)
.map(
pair => `- ${pair[1][1][1]} ${pair[1][0][1]}`
)
.join("\n\n")
};
// --------------------- GENERIC ---------------------
// fst :: (a, b) -> a
const fst = tpl =>
// First member of a pair.
tpl[0];
// groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
const groupBy = eqOp =>
// A list of lists, each containing only elements
// equal under the given equality operator, such
// that the concatenation of these lists is xs.
xs => 0 < xs.length
? (() => {
const [h, ...t] = xs;
const [groups, g] = t.reduce(
([gs, a], x) => eqOp(a[0])(x)
? [gs, [...a, x]]
: [[...gs, a], [x]],
[[], [h]]
);
return [...groups, g];
})()
: [];
// groupOnKey :: Eq k => (a -> k) -> [a] -> [(k, [a])]
const groupOnKey = f =>
// A list of (k, [a]) tuples, in which each [a]
// contains only elements for which f returns the
// same value, and in which k is that value.
// The concatenation of the [a] in each tuple === xs.
xs => 0 < xs.length
? groupBy(a => b => a[0] === b[0])(
xs.map(x => [f(x), x])
)
.map(gp => [
gp[0][0],
gp.map(ab => ab[1])
])
: [];
// 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)
: [];
return main();
})();
You could copy to a variable (or clipboard) and then search for the regular expression Source: S\d+ and replace with nothing. (\d is any digit and + means one or more)
To reverse the order of the lines you could do a For Each line in (variable/clipboard) Prepend Line to NewVariable... which will then have the lines in reverse order. I've attached a crude attempt that may help
Echoing @ComplexPoint -- it isn't clear if "Source" is the first word of an entry or if they do actually start with bullets or similar. And you seem to have two entries in your source but only one in your expected output -- I'm going to assume there should be two.
Assuming it is the first word, it sounds like what you want is to
Delete from the start of every line the text "Source:" and a space and an "S" and one or more numbers and a space
Reverse the lines
For the first, you can delete with "Search and Replace" -- search for your pattern and replace with nothing (leave the box empty). Being ultra careful and pinning the pattern to the beginning of the line, something like
(?m)^Source:\sS\d+\s
...should work.
For reversing lines, just use the "Filter" action with "Reverse lines" selected.
Putting those together, and working on the System Clipboard so you can Copy, run the macro, Paste the transformed text:
I'm sure these people are giving you good advice, but my Filter Utility can do it all in one action, assuming you pass the data into my macro using a variable, like this:
(I was planning to make that change for v1.1 of my macro.)
This solution may give you a few things to handle separately. For example, I don't know what app you are using so I don't know if this will deal with the bullets properly. Also, you may end up with a leading or trailing space, but that should be easy to fix. Also, I didn't deal with the copy/paste part of your problem, partly because I don't know which app you are using.
My macro can be found here:
My macro is designed to work with plaintext, while your problem also requires dealing with an app that is probably RTF, not plaintext. But my macro can still do most of the heavy lifting in a really simple interface for you.
Sorry - I pasted the text directly, and the asterisks became a bullet. They start with "* Source: " - I've gotten some hints here that i think I can work with - I'll see if I can figure out at least how to do "one" set and then we'll go from there.