Make one letter bold in text component

Dear all,

Is there a way to make one part of the text in the text component in the builder bold? Couldn’t find the right information on how to do this. Is there a way (in the component or otherwise in a new code component?)?

Best regards, Sanne

If this template helps then use it. If not then just delete and start from scratch.

OS (e.g. Win10):
PsychoPy version (e.g. 1.84.x):
Standard Standalone? (y/n) If not then what?:
What are you trying to achieve?:

What did you try to make it work?:

What specifically went wrong when you tried that?:
Include pasted full error message if possible. “That didn’t work” is not enough information.

Unfortunately there is not, bold is a property of the entire text component, not of each letter, so you can only set it to be either all bold or all not. Now that we have a Textbox component which deals with each letter as it’s own “glyph”, this is more possible to implement, but the Textbox is still very new and only in Beta.

You could create a separate component just for the letter you want to be bold and line it up to precisely where it should be, but you’d have to be very careful with Position, especially if you’re conducting this experiment across multiple different displays.

Thank you for your response. Good to know then I will not spend any more time looking for solutions. I will try and otherwise just not make it bold, the option with space sounds as if they could cause errors/ugly screens.

However, if I want to make text bold, how can I do this in the text component? I tried different codes but the programm did not react. Or should this be in a code component?

If you replace your Text component with the new Textbox component then that has an attribute called “bold”, currently it’s under Format but (especially as it’s in Beta) we may be moving it soon.

Addendum: in the new TextBox2 you can make a single letter bold as well! I’ve set it to use the old-school html tags of <b></b> around the letters you want bold (and similarly <i></i> for italics). Note that this is a “fake” bold/italic where we don’t actually use the font designer’s bold character. Instead we take the regular character and just make it 10% wider than usual!

1 Like

@ TParsons and jon

That sounds great. Where can I find this new text component? I only see one in the Builder… (version 3.2.4)

I think, you’d need to use a code component. I couldn’t find online documentation, but from the interactive shell in the coder view, you can read the docstring with:

from psychopy import visual
help(visual.TextBox2)
1 Like

This is added in 2020.2 and documentation is to follow

1 Like

Hi Jon,

Is there a way to also get this to work with text pulled from a conditions file or code? I’m getting a syntax error whenever there’s a $ in the textbox.

Ah, that’s a bit of confusion over the use of $

$ doesn’t quite mean “this is a variable” it means “treat this (all) as code”

In your case the code you want would be one of the following (they are equivalent):

  • "<i> "+Word+" </i> - "+captured_string
  • "<i> %s </i> - %s" %(Word, captured_string)
  • "<i> {} </i> - {}".format(Word, captured_string)
  • f"<i> {Word} </i> - {captured_string}"

If you need JavaScript to work then you should use the first one. The last one is the neatest but requires Python3 (which you probably have) and you need to note the little f at the beginning of the quotation. These are known in python as f-strings or formatted strings.

Take one of those options and precede the whole thing with $ in your dialog box like this:
$f"<i> {Word} </i> - {captured_string}"

2 Likes

Hi @jon,

Is there anyway to do the same thing for underline (ie, underlining 1 word in a sentence)?

I’ve also tried to run

$'NOT UNDERLINE ' + '\033[4m' + 'UNDERLINE' + '\033[0m' + ' NOT UNDERLINE'

(hoping it will be equivalent to print('NOT UNDERLINE ' + '\033[4m' + 'UNDERLINE' + '\033[0m' + ' NOT UNDERLINE')) but that doesn’t work either.

You can do something that approximates an underline using unicode character \u0332 after each letter you want underlined. So you can do this:
text = "H\u0332e\u0332l\u0332l\u0332o\u0332 was underlined"
to get
'H̲e̲l̲l̲o̲ was underlined'
but these are characters with underscores and the exact look will depend on the font being used. The lines may or may not quite touch and they may or may not be on the same vertical position depending on the font creator’s decisions.

To make it easier to read your own text you can use this funky code:
'\u0332'.join('Hello')+'\u0332'
which is using the underscore to “join” all the letters in the word “Hello” (so it puts 1 in between each character) and then adding one more to handle the final character

Similar options with other chars:
'\u0331'.join('Hello')+'\u0331' non-joined underline: 'H̱e̱ḻḻo̱'
'\u0336'.join('Hello')+'\u0336' strike-through: 'H̶e̶l̶l̶o̶'
'\u0333'.join('Hello')+'\u0333' double underline: 'H̳e̳l̳l̳o̳'

Thanks for your response @jon!

When I tried print('\u0332'.join('Hello')+'\u0332') in psychopy coder python shell, I got the following error:

>>> print('\u0332'.join('Hello')+'\u0332')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files\PsychoPy\lib\encodings\cp1252.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\u0332' in position 1: character maps to <undefined>

When I tried $'\u0332'.join('Hello')+'\u0332' in a Builder textbox, I got a format error (attached image).

underline_error

I’m currently using Psychopy v2022.1.3 standalone installed on Windows 10.

Below is the default encoding

>>> import sys
encoding = sys.getdefaultencoding() 
print(encoding) 
utf-8

Ah, apologies. I thought that would work.

Actually for me it does work in Coder’s shell (on macos) but that’s most likely a difference in fonts

On Python, it’s clear that the TextBox will need some more work in order to support these combining characters, because they’re technically 2 characters that know how to print as 1. We’ll look into it but that won’t be until at least the next winter release (Jan/Feb 2023)

On PsychoJS (online) I haven’t yet tried to see what happens. It may “just work” there!

Hi @jon ,

should this already work online?
I have text defined in a code component, as text variation depends on the group participants are in. I tried: text = “blabla part of the text in bold blabla” but it doesn’t work. I also tried puting f in front: text = $f"…" and wrap “part of the text in bold” between { }. Am I doing something wrong or is this a Pavlovia problem?

I’m afraid that means the feature isn’t yet working on the web version of the library (which was a complete rewrite to use JavaScript instead of Python). In that case the workaround options are:

  1. either use multiple Textboxes, with one of them set to the bold test and others set to the not bold text
  2. generate images of what you want to present (if there aren’t too many) and present those images instead

Although option 2 will take longer it has the benefit of allowing you to specify the formatting of your text completely

Conversely it seems that we now have a way of displaying bold online which doesn’t work locally.