duskmoon314 / typst-fontawesome

A Typst library for Font Awesome icons through the desktop fonts.
https://typst.app/universe/package/fontawesome
MIT License
14 stars 0 forks source link

Using ligatures (FA Pro) leads to icon conflicts #11

Closed adrfantini closed 1 month ago

adrfantini commented 1 month ago

I'm using FA Pro and, as reported in #2, the Pro icons are used with ligatures. This leads to issues such as #10, but also to the fact that there are conflicts between the icons.

For example, trying to use an icon arrow-down-right will result in arrow- followed by the down-right icon.

Example result: image

duskmoon314 commented 1 month ago

Wow, this is not good. 😢

I assume the typst looks up the glyph after the line breaks, so this is also a typist/typst#2578-related issue.

adrfantini commented 1 month ago

Wow, this is not good. 😢

I assume the typst looks up the glyph after the line breaks, so this is also a typist/typst#2578-related issue.

Would it be possible to use the same approach you used for the basic icons for Pro as well?

duskmoon314 commented 1 month ago

Would it be possible to use the same approach you used for the basic icons for Pro as well?

I just extracted the icons' names, aliases, and Unicode from the Free version's metadata.json file. If a JSON exists for the whole Pro set, the Python script can be used to generate the map.

I have come up with the idea of writing a scrapper to extract all metadata from Fontawesome's website...

adrfantini commented 1 month ago

Would it be possible to use the same approach you used for the basic icons for Pro as well?

I just extracted the icons' names, aliases, and Unicode from the Free version's metadata.json file. If a JSON exists for the whole Pro set, the Python script can be used to generate the map.

I have come up with the idea of writing a scrapper to extract all metadata from Fontawesome's website...

What info do you need to extract from the JSON? I'm not sure if there is such a file for the Pro, but there are other files which might contain the same data

A quick copilot request returned this:

from fontTools.ttLib import TTFont

def extract_info(font_path):
    font = TTFont(font_path)
    # Extract Unicode values and glyph names
    unicode_map = font.getBestCmap()
    for unicode_val, glyph_name in unicode_map.items():
        print(f"{unicode_val:04X},{glyph_name}")

    # Extract ligature (alias) information
    # This part is more complex and depends on the specific structure of the FontAwesome font
    # FontAwesome uses the GSUB table for ligatures, which map sequences of characters to a single glyph
    gsub_table = font["GSUB"].table
    # This is a simplified example; actual extraction requires navigating the GSUB table's structure
    # and may vary depending on the font version and structure

    # Close the font file
    font.close()

font_path = 'my_path/Font Awesome 6 Pro-Regular-400.otf'
extract_info(font_path)

Result: https://pastebin.com/e7KiFhni

duskmoon314 commented 1 month ago

Wow, that is enough for your use case.

You can build up a dictionary from the output in this form:

#let fa-pro-icon-map = (
  "<icon-name>": "\u{<unicode>}",
)

Take a look at lib-gen.typ for an example.

Then you can pass it to fa-icon:

#let fa-icon = fa-icon.with(font: "Font Awesome 6 Pro", fa-icon-map: fa-pro-icon-map)

After that, Unicode is used if the name can be found in the dictionary.

I think the method of extracting information from font files may lack icon aliases, but that is only gilding the lily.

Another issue that might occur is the solid version may not be found since typst treat Font Awesome 6 Free Regular and Font Awesome 6 Free Solid as two fonts.

adrfantini commented 1 month ago

Mmmh, I generated the map and I'm using:

#let fa-pro-icon-map = json("fontawesome/fa-pro-icon-map.json")
#let fa-icon = fa-icon.with(
  font: "Font Awesome 6 Pro",
  hyphenate: false, // See https://github.com/duskmoon314/typst-fontawesome/issues/2#issuecomment-2230228814
  fa-icon-map: fa-pro-icon-map // See https://github.com/duskmoon314/typst-fontawesome/issues/11
)

Here's the map: https://pastebin.com/kFSzVznG

But it's not working: Screenshot_20240717_120336

(notice that some icons are stacked since I'm using #12 )

duskmoon314 commented 1 month ago

I haven't tested JSON before. I assume typst takes "\u{f445}" and doesn't translate it to Unicode sequence.

You can just generate a typst file and include the map:

  1. Rename the JSON to typst file and use regex to replace \\u.
  2. Add #let fa-pro-icon-map = to the front.
  3. Include the map in your main file.
adrfantini commented 1 month ago

I haven't tested JSON before. I assume typst takes "\u{f445}" and doesn't translate it to Unicode sequence.

You can just generate a typst file and include the map:

  1. Rename the JSON to typst file and use regex to replace \\u.
  2. Add #let fa-pro-icon-map = to the front.
  3. Include the map in your main file.

I'm unsure why my solution did not work, I assume that the escaping was incorrect? In any case, including a .typ file works!

Feel free to close unless you want to solve this in a more generic way

duskmoon314 commented 1 month ago

I found that FontAwesome provides a GraphQL API for getting icon metadata. I have written a simple script to get icons of v6.6.0 and generated a typst file lib-gen.typ that can be found in PR #13.

Can you please help me check whether the generated typst file covers your usage? If so, we can support icons from pro sets more easily.