diff --git a/components/skills.typ b/components/skills.typ new file mode 100644 index 0000000..3b8b64b --- /dev/null +++ b/components/skills.typ @@ -0,0 +1,56 @@ +#import "../utilities/localize.typ": localize + +#let skill(data, language) = { + // Determine the color to use for the proficiency percentage bar. + let proficiency_color = if "color" in data { + // If there is a color defined in the data, use `eval()` to convert it to a + // Typst color. + eval(data.color) + } else { + // Otherwise if no color is defined default to black. + black + } + + let proficiency_percentage = str(data.proficiency) + "%"; + + // Use a stack to position the text and percentage bar from top to bottom. + stack( + dir: ttb, + // And use a grid to position the skill text and percentage number from + // left to right. + grid( + columns: (1fr, auto), + localize(data, "name", language), + proficiency_percentage, + ), + // Add a tiny amount of vertical space so the bar doesn't overlap the text. + v(4pt), + // Then render the bar as two lines where the grid columns determine how + // long they both are. Initially I tried to do this with a linear gradient + // and using the percentage as a color stop, but it left a small fade in + // between the colors which I didn't want. + grid( + // We have to use `eval()` for the percentage here as it's still a string + // at this point and Typst expects a ratio type to calculate with. + columns: (1fr, 100% - eval(proficiency_percentage)), + line(length: 100%, stroke: 1pt + proficiency_color), + line(length: 100%, stroke: 1pt + silver), + ), + ) +} + +#let skills_section(data, language) = { + block(stroke: (left: 1pt + black), outset: (left: 0.75em), [ + == #localize(data.locale, "skills", language) + + // Define all the sections to render, the order here also determines the + // render order. + #for skill_section in ("language", "general", "software", "platforms") [ + === #localize(data, skill_section, language) + + #for data in data.skills.at(skill_section) { + skill(data, language) + } + ] + ]) +}