hugo
hugo copied to clipboard
Support CJK in images.Text, add width and height as optional args
When I started using Hugo, I was really drawn to the "images.Text" feature. I'm trying to use this to generate images for the Open Graph Protocol.
Since it does not support CJK, it is in a state where it is not wrapped as shown below.
{{- $font := resources.Get "/fonts/NotoSansJP-Bold.ttf" -}}
{{- $img_base := resources.Get "/img/ogp.png" -}}
{{- $img_base = $img_base.Filter (images.Text "あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみぬめもあいうえおかきくけこさしすせそたちつてとなにぬねの" (
dict
"color" "#ffffff"
"size" 60
"linespacing" 2
"x" 130
"y" 220
"font" $font
)
)
-}}
Workaround
As a workaround, it can be handled by separating with spaces at moderate intervals, but I thought it would be easier to use if you could define a text area like a CSS margin. Could you consider adding it as a feature?
- Avoidance example
{{- $img_base = $img_base.Filter (images.Text "あいうえおかきくけこさしすせそ たちつてとなにぬねのはひふへほ まみぬめもあいうえおかきくけ こさしすせそたちつてとなにぬねの" (
dict
"color" "#ffffff"
"size" 60
"linespacing" 2
"x" 130
"y" 220
"font" $font
)
)
-}}
Could you consider adding it as a feature?
Yes, I can see how that would be useful (even for non CJK languages), but I'm not totally sure how the API would look like.
- I guess a
width
(of text block, in pixels) would make sense. - But how do we break words?
Thank you for having interest.
- I guess a
width
(of text block, in pixels) would make sense.
My first thought was to fit the page title in the blue border of the image. Therefore, I decided to output a character string in Font size (size: 60), check the number of characters that fit, and insert a space there to make a line break. In order to make this mechanical, I thought that if the margins on the four sides could be defined, it would be possible to calculate from the font size, which is the reason why I made the proposal.
- But how do we break words?
Japanese is very difficult, so even Japanese people have different opinions on where to cut phrases and words (laughs). I don't think it's worth the cost to do it with Hugo, so I think the following is fine.
- Allow setting margins on "images.Text"
- Calculate whether it exceeds the margin size and break a line.
-
CJK
: Line break before 1 character exceeding margin. -
Not CJK
: line break before the word.
-
- Option: Support for newline characters, etc., so that users can break lines. Example:
\n
, etc.
- Calculate whether it exceeds the margin size and break a line.
The projects below may be helpful. I initially thought about using it, but it seemed incompatible with the environment I was using, so I wanted to use Hugo's functions. Ladicle/tcardgen: Generate a TwitterCard(OGP) image for your Hugo posts.
In the case of CJK, this project seems to be output as follows, and it seems that Japanese clauses are not conscious
In order to make this mechanical, I thought that if the margins on the four sides could be defined, it would be possible to calculate from the font size, which is the reason why I made the proposal.
Yea, we could do something like that.
I guess the left/top margin is somehow covered by the current x/y parameters.
What if we make it top
, right
bottom
, left
?
And retire/alias x/y.
Plan1
I thought about several patterns, but I felt that the optimum was different depending on the person. If you want to think about the design and put it there like me, you can substitute "x,y" of "images.Text" for the upper left specification. And if you can define the lower right coordinates, it seems that you can define the square (gray part) of the text box. I'm excited that I can write like this when writing in config.yaml
# config.yaml
params:
opengraph:
x: 120 # images.Text x
y: 240 # images.Text y
bottom_right:
x: 1160
y: 590
Plan2
On the other hand, while drawing a diagram, I thought that it might be easier to use if the width
and height
were input. The reason for calculating and using the lower right coordinate is that the size of the image you want to use "images.Text" must be the same.
In this case, simply control the width so that the characters do not exceed the x-coordinate, and the height is the same.
I felt that it was intuitive and easy to understand even if it became an option of "images.Text".
{{- $img_base = $img_base.Filter (images.Text "あいうえおかき…" (
dict
"color" "#ffffff"
"size" 60
"linespacing" 2
"x" 120
"y" 240
"width" 1040
"height" 350
"font" $font
)
)
-}}
Therefore, I personally think that Plan2 may be more beneficial for those who want to use it in the future, so how about this?
I like plan 2, easy to understand.
It will be nice, if letterspacing
option can be introduced.
If introduced, the modified plan 2 will look like this:
{{- $img_base = $img_base.Filter (images.Text "あいうえおかき…" (
dict
"color" "#ffffff"
"size" 60
"linespacing" 2
"letterspacing" 1
"x" 120
"y" 240
"width" 1040
"height" 350
"font" $font
)
)
-}}
letter-spacing
is a nice feature. I did not know this CSS property.
It might be useful if some users want to have equally spaced letters in width and height boxes.