Request for a new token: %CompositeTextWidth%

There's a feature in Keynote that lets me indicate that any text inserted into a box will be "shrunk to fit" the box, so that any amount of text will fit into the box and always be displayed (albeit very small if the text is very long.)

It reminds me a little of the KM option called "display large" in the "Display Text" action, however Keynote (KN?) supports line wrapping while KM does not. Line wrapping is important to me. And the KM way of doing things doesn't give me any control over how long the large message lasts, or what it's transparency should be.

If I want to do text wrapping combined with "shrink to fit" in KM, it seems I'll have to do it manually using the action "Composite Text onto Image" but that's not very effective because the action doesn't tell me how far across the image the text was successfully written. May I request a new KM token called %CompositeTextWidth% which returns the text's output width of its most recent action? In a way, this is in keeping with the approach of some other tokens like %FoundImage% which also returns useful data from an action.

I found a way to generate styled text of a given font size using the textutil command in macOS. That could help me a lot, but it still won't tell me how wide the text became when I wrote it into an image. So it's only half the solution to my problem. But here it is for those who are interested:

textutil -stdin -stdout -convert rtf -font Arial -fontsize 32

So you need text-wrap a sentence?
I’d count characters to limit line length,
and do a LineFeed after the end of a word.

This is customizable. See

I really don't think this is ever going to happen.

If you want more control over the display of text, you should probably use the Custom HTML Prompt action.

1 Like

Your suggestion is much appreciated. But it doesn't solve my problem. I need the text to wrap and shrink. Your idea addresses the wrapping, but doesn't address the shrinking. How exactly do you intend for me to write code that shrinks the text so that it all fits and yet is as large as possible?

I would indeed use Custom HTML Prompt if there was some way in HTML code to get text to be as large as possible but still fit within the display window. I've browsed through some HTML commands, but couldn't find any such thing. So I don't think it meets my needs at all. But thanks for the tip.

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.