Request for a new token: %CompositeTextWidth%

That's a fair point, Martin, and thanks, but as I said that feature doesn't include word wrapping so it's of no use to me. I was using that as an example of "shrink to fit" so people would know what I meant. Apparently not everyone that replied to me understands this requirement of mine.

Peter,

I found an inconsistency (perhaps an error) between how KM's Execute Shell Script works and the command line.

In the command line, if you do this:

echo "BIG WORDS" | textutil -stdin -stdout -convert rtf -font Arial -fontsize 32 | pbcopy

... then the resulting data placed into the system clipboard is real styled text in 32 point font. But if you do the same thing using KM, as follows:

image

... then you get plain text only (with RTF codes inserted.) Not styled text. I think I have a good hunch why this is, but it's not the desired behaviour. The KM action should be honouring the actual style in the shell's output rather than forcing styled text into plain text. The command line works as we want it to work, but the KM action works differently. Without this ability, I can't programmatically scale the font as needed. Unless someone has another idea. How else can I generate styled text using a font size that I indicate programmatically?

I'm not quite getting it, why don't you use the following in KM? (The result will then be passed on to the clipboard directly.)

@peternlewis responded to a customization request for the Display Text Large action before.

I wish there can be more customization options too. But I doubt it would happen.

The Custom HTML Prompt is probably the path to go...

The reason I didn't want to use that is because the clipboard is a global variable. That means the macros or even the user through the GUI could damage the contents of that global variable. There is no reason we shouldn't be able to use local variables for this task.

If that's true, then how exactly do you think I should programmatically calculate the size of the fonts in the HTML code that you want me to generate? I'm trying to solve the problem, which is calculating the size of the font required. Using that action has nothing to do with the problem.

Oh. I'm sorry. I was thinking about "Display Text" with "line wrapping" in your OP.

Okay, no worries. The line wrapping is determined by the size of the font. And the size of the font is determined by the size of the window. Oddly enough, there may be more than one valid solution to this problem.

I believe that when Peter encoded the Execute Shell Script action he probably just forgot to assign the type of the action's output to the System Clipboard. I think it's just a minor programming error, not a design decision. I can't think of any reason that the type of the data should not be assigned to the system clipboard, EXACTLY as the shell does it. If the Shell can do it, why can't the Execute Shell Script action? how do you explain that difference?

There is no “actual style” of a shell pipe. A pipe is just a sequence of bytes, it has no style/type associated with it.

pbcopy decides to interpret the stream of bytes that starts with {\rtf1 as RTF and process it before it is stored in the clipboard. But this is not without problems. For example, if you run the command:

echo '{\rtf1 is what RTF files start with' | pbcopy

You get a broken clipboard, not the text that you sent to pbcopy.

So maybe Keyboard Maestro should do the same, or maybe it shouldn't - its not a clear cut case.

You can use some JS and HTML:

https://pierredarrieutort.github.io/fitext/

I don't know if you have any proficiency with HTML or CSS, so this is a deep dive either way, but there are a couple of CSS keywords, notably clamp, that enable fluid topography to be realized.

Take a read here and see if it's something you believe you're able to work out. What you're trying to do is completely achievable with HTML and CSS.

2 Likes

tried calc and clamp but seems KM rendering engine doesn't support them?
@peternlewis

⠀⠀⠀⠀⠀⠀

⠀⠀⠀⠀⠀⠀

@Sleepy try this in a HTML prompt:

<html>
<head>
<style>
h1, p  { font-size: 4vw; }
</style>
</head>

<body>

<h1>
  Article Title
</h1>

<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Totam ab vitae consequatur dignissimos amet, nisi recusandae, voluptate, dolore autem repellat sit doloremque facilis? Libero quos autem nesciunt nemo unde aut.</p>

</body>
</html>

Demonstration:

Jul-24-2021 11-01-21

That is illuminating and surprising. Wow. I guess I was wrong (20% of everything I say is wrong.) Does this mean I am not able to pass data (as styled text) from a variable to the KM action "Composite Text onto image"? I wasn't expecting that.

I'm so used to being able to insert variables into text fields in KM, I was under the impression that I could insert styled text into the "Composite Text onto Image" action in KM, but apparently not, now. That's frustrating. This might be the reason you were looking for, but if it's not sufficient for you, I accept that. (And I thank you for recognizing that you could do that if you wanted to.)

That may leave me with Javascript as the only solution.

I was prepared for some hard work. This is just a little harder than I was hoping for.

I never knew about the phrase "fluid typography", but now that you've given me that phrase, it's much easier to google what I need. I really tried googling this idea, but without those words I wasn't having much success. Thanks.

I've just spent 10 minutes looking over the examples. The examples that I looked at are "approximate" algorithms. For example, they adjust the font size based on a formula that (seems to) takes the window dimensions and creates an estimated font size, like this:

font-size: calc(14px + (26 - 14) * ((100vw - 300px) / (1600 - 300)));

This sort of algorithm is something I would consider valid for building a prototype app, which I'm indeed doing now, but not for a final product. The calculation above is more like a "shrink to probably fit" algorithm, not a "shrink to fit" algorithm. If you look at Apple's Keynote application, it has an actual "shrink to fit" that works 100% of the time. No approximations. Check it out. It really works. The examples on that website are inaccurate imitations.

No doubt there is a way using Javascript to solve this problem, but it's a much more complicated problem than even that website addresses. For Javascript to work, there has to be a way to get the width of the displayed string in a given font. Without this information, it cannot be done. The information exists somewhere, since Keynote accomplishes the job. My gut tells me that Keynote is NOT taking advantage of any private APIs.

You would need to couple the above with JavaScript for a bullet proof implementation. JavaScript could determine the exact size of your text container and the exact pixel dimensions of your string and do the dirty work.

Like I said, it's a deep dive if you're new to the language(s). If you post your working prototype (or even a much more detailed explanation of what you're shooting for) I'd be glad to see if I could point you in the right direction. Here's some further reading on fitting text using a combination of tech.

If Javascript can get the exact pixel dimensions of the string that was output, then Javascript could be a solution. But most of those examples that you showed me do NOT get the pixel dimensions of the outputted text. They just cheat, which I can do well enough without examining their code. I am very good at creating algorithms that cheat to get approximate results.

MAGICNUMBER - is just an approximator
FITTEXT - is just an approximator, and requires additional software called jquery to work
TEXTFIT - is just an approximator
FITTY - might work, can't be sure, no video demos to see, I may need to download it
TEXTFILL - might work, can't be sure, no video demos to see, but requires additional software
FLOWTYPE - does not scale the text to fit the box, it just scales the text as a function of box size
SVG - no URL was provided, so I can't tell how it works, but it claims to require magic numbers

I truly appreciate your tips and your knowledge. But when I visited the websites and, in some cases, found videos or simulators of the javascript in action, the videos made it clear that they don't do what I want. My requirement is to get text that ALWAYS fits in its box. If you don't know what I mean, try using Keynote and experiment with its "Shrink to Fit" option. Keynote does precisely what I want, while these routines, at least most of them, don't.

There must be a system API that they use to obtain the width of the outputted text. How else could they possibly work if not through an API? Hopefully they aren't reading the pixels directly off the screen to see how the text was written. Do you know which API they would use or what the name of the API routine is?

There's no point in showing you my cheating code because it's not what I want anyway. I want something that isn't an approximator.

If Keynote can do it, it's doable. And I'm fairly sure it's done with the assistance of a macOS API. All I need to do is find out what that API is and then use a language that can access that API.

The nice video (GIF) you provided shows that that is definitely not what I want. The video shows that the scaling is very inaccurate resulting in a window that's sometimes 75% blank. I want an algorithm that shrinks to fit. And when I say "fit" I mean 100% fit, not 50% fit.

If you take a look at Keynote's "Shrink to Fit" you will see what I want. It works perfectly. That's what I want. I don't want approximations that are often 50% over-shrinking or 20% under-shrinking. I can write my own approximations using the built in actions in KM, so I certainly don't need Javascript to do that.

I am sorry if I sound frustrated. I know you're all trying to get me closer to a partial solution. And I appreciate that. But I've already got a half-baked solution. What I want is an actual real solution. That's why I suggested %CompositeTextWidth%. If there was such a token, I could write a solution that always came up with the correct answer. (Well, %CompositeTextHeight% would also be needed, but I didn't want to push my luck in my original post.)

@Sleepy oh I see, now I understood what you were talking about.

Hey there @Sleepy, I just happened upon this jQuery plugin and thought of you.
Might fit the bill (if you've not already found a solution).

1 Like

Rather than have Keyboard Maestro automagically interpret RTF as attributed strings, I have added explicit filters to convert Attributed Text (in clipboards) to/from RTF text for the next version.

3 Likes