TransWikia.com

Styling substring of label with different style without creating two separate label rules?

Geographic Information Systems Asked by Encomium on December 1, 2020

This question has been asked in the past but those questions were either not answered or suggested solutions that required multiple labels separated by newlines and placement rules to simulate a contiguous label.

Does the label engine in QGIS currently allow styling substrings based on rules? I’m writing a quick tutorial for a GIS class on labelling, and I’m seeing if a label like this:

"name_en" ||  'n'  ||  'is a ' || lower("category") || ' site which is ' || case when "danger" = 1 then 'under threat.' else 'not under threat.' end 

Can be modified so that the contents of the field "name_en" is displayed in bold, whereas the rest of the string is displayed using regular font. For reference, the data in question is UNESCO’s list of World Heritage Sites, available here.

I can get there by splitting them up in two and devising a rule for "name_en" separately, but that feels like a wonky solution. I’ve tried several expressions in the 'data defined override' button, but the result always comes back as either all bold or all regular. It expects a boolean argument, so that kind of assumes the output (i.e. any given label) will always be either all bold or all regular.

I assume the answer will involve something like using the length of the name_en string to apply the bold style to the first n characters, or:

left(len(name_en))

But I’m not finding a way to use that kind of logic to style a substring of a label.

One Answer

If you are not bound to a specific font (those characters might be missing for some), you can abuse special Unicode characters for this. This is the same trick people use to have bold or cursive text on social media.

https://boldtext.io/ has a pretty thorough explanation and the characters ready to copy and paste.

The other pre-condition is that you must be willing to do some awful hacking.

You can use the special characters with the replace function in the label expression. Your expression will become really awkward, long and hard to maintain if you start having too much fun.

Here is an example using Natural Earth data, you can enter world in the coordinate indicator at the bottom of the QGIS screen and hit Enter to load the data set I used.

with_variable(
  'normal_characters',
  array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3','4','5','6','7','8','9'),
  with_variable(
    'bold_characters',
    array('?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?'),
    replace("NAME", @normal_characters, @bold_characters)
    || 'n'  ||  'has the ISO A3 code ' ||
    with_variable(
      'fraktur',
      array('?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?'),  -- no numbers
      if(
        "ISO_A3" = 'DEU',
        replace("ISO_A3", array_slice(@normal_characters, 0, 51), @fraktur),  -- only the first 52 normal characters
        "ISO_A3"
      )
    )
  )
)

enter image description here

Correct answer by bugmenot123 on December 1, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP