From 8c3266d8b16e175431ccd25e718fd37e0196483d Mon Sep 17 00:00:00 2001 From: Fini Jastrow Date: Mon, 26 Aug 2024 17:11:47 +0200 Subject: [PATCH] Devicons: Prepare update This adds the current mapping file (which has been hand-crafted) and the scripts to update the Devicons. This also fixes Vorillaz' typo 'rasberry_pi' -> 'raspberry_pi'. Signed-off-by: Fini Jastrow --- src/glyphs/devicons/README.md | 15 +-- src/glyphs/devicons/analyze | 163 +++++++++++++++++++++++++++ src/glyphs/devicons/generate | 120 ++++++++++++++++++++ src/glyphs/devicons/mapping | 202 ++++++++++++++++++++++++++++++++++ 4 files changed, 493 insertions(+), 7 deletions(-) create mode 100755 src/glyphs/devicons/analyze create mode 100755 src/glyphs/devicons/generate create mode 100644 src/glyphs/devicons/mapping diff --git a/src/glyphs/devicons/README.md b/src/glyphs/devicons/README.md index 6d0f3ba56d..1e65ebe27b 100644 --- a/src/glyphs/devicons/README.md +++ b/src/glyphs/devicons/README.md @@ -1,12 +1,13 @@ # Devicons -For more information have a look at the upstream website: https://github.com/vorillaz/devicons +From the Devicons the non-linemark versions are selected and assembled into a custom +icon font. This font guarantees that the codepoints of existing icons do not change +when other icons are added or removed. -This is taken directly from the repository default branch, which is ahead of release 1.8.0. -We call it 1.8.1 here, but there is no such release. +For more information have a look at the upstream website: https://github.com/devicon/devicons -## Source bugs fixed +The helper scripts need to be called in this order (note the individual prerequisites): +* `analyze` +* `generate` (possibly via `fontforge`) -Glyph 0xE6B6 is defective in the original font. We hand optimized and fixed that. - -Version: 1.8.1 +Version: 2.16.0.custom diff --git a/src/glyphs/devicons/analyze b/src/glyphs/devicons/analyze new file mode 100755 index 0000000000..9f55fb58b0 --- /dev/null +++ b/src/glyphs/devicons/analyze @@ -0,0 +1,163 @@ +#!/usr/bin/env python3 +# coding=utf8 + +# Create a new mapping file by combining the information from +# the old mapping and checking which icons got dropped; are new; +# or get a different svg file. + +# PREREQUISITES: +# $ curl -OL https://github.com/devicons/devicon/archive/refs/tags/v2.16.0.tar.gz +# $ tar zxf v2.16.0.tar.gz +# $ mv devicon-*/icons . +# $ cp -r vorillaz icons + +import re, os, sys + +vectorsdir = 'icons' + +def filename_from_name(filename): + """ Some icons have a name that is not the svg filename """ + # Returns '-' if the icon is to be removed + # Giving a full pathname selects a certain svg variant + return { + 'aws': 'amazonwebservices', + 'backbone': 'backbonejs', + 'bower': 'bower/bower-line.svg', + 'clojure': 'clojure/clojure-line.svg', + 'composer': 'composer/composer-line.svg', + 'css3_full': 'css3/css3-plain-wordmark.svg', + 'digital_ocean': 'digitalocean', + 'dotnet': 'dot-net', + 'ghost': 'ghost/ghost-original-wordmark.svg', + 'ghost_small': 'ghost', + 'github': '-', + 'github_alt': '-', + 'github_badge': 'github', + 'github_full': 'github/github-original-wordmark.svg', + 'go': 'go/go-line.svg', + 'grunt': 'grunt/grunt-line.svg', + 'ie': 'ie10', + 'javascript_badge': 'javascript', + 'javascript': '-', + 'jekyll_small': 'jekyll', + 'krakenjs': '-', + 'krakenjs_badge': 'krakenjs', + 'meteorfull': 'meteor/meteor-plain-wordmark.svg', + 'nodejs': 'nodejs/nodejs-plain-wordmark.svg', + 'nodejs_small': 'nodejs', + 'raspberry_pi': 'raspberrypi', + 'ruby_on_rails': 'rails', + 'symfony': '-', + 'symfony_badge': 'symfony', + 'unity_small': 'unity', + 'windows': 'windows8', + }.get(filename, filename) + +def get_aliases(names): + """ For some icons we would like to have aliases """ + # Returns a list with aliases, keep main name first element + name = names[0] + alias = { + 'digital_ocean': [ 'digitalocean' ], + 'github_badge': [ 'github' ], + 'javascript_badge': [ 'javascript' ], + 'jekyll_small': [ 'jekyll' ], + 'krakenjs_badge': [ 'krakenjs' ], + 'ruby_on_rails': [ 'rails' ], + 'symfony_badge': [ 'symfony' ], + 'unifiedmodelinglanguage': [ 'uml' ], + }.get(name, [ ]) + while name in alias: + alias.remove(name) + return [ name , *alias ] + +def file_with_ending(files, ending): + """ Return the (first) file out of a list of files that has the desired ending """ + # Returns False if no match at all + matches = [ file for file in files if file.endswith(ending) ] + if not matches: + return False + return matches[0] + +def suggest_new_filename(name): + """ Return a specific svg filename for one icon, preferring some svg filename endings """ + name = filename_from_name(name) + subdir = vectorsdir + '/' + name + if not os.path.exists(subdir): + return False + if os.path.isfile(subdir): + return name + svgs = os.listdir(subdir) + filename = file_with_ending(svgs, 'plain.svg') + if not filename: + filename = file_with_ending(svgs, 'original.svg') + if not filename: + filename = file_with_ending(svgs, 'plain-wordmark.svg') + if not filename: + filename = file_with_ending(svgs, 'original-wordmark.svg') + if not filename: + return False + return name + '/' + filename + +remix_mapping = [] +with open('mapping', 'r') as f: + for line in f.readlines(): + if line.startswith('#'): + continue + c1, c2, n, *f = re.split(' +', line.strip()) + remix_mapping.append((int(c1, 16), int(c2, 16), n, *f)) + +new_names = os.listdir(vectorsdir) +new_names.sort() +new_names.remove('vorillaz') # If this fails one prerequisite step is missing + +notes1 = '' +notes2 = '' +mapping = [] +for orig_point, dest_point, filename, *names in remix_mapping: + if not os.path.isfile(vectorsdir + '/' + filename): + newfilename = suggest_new_filename(names[0]) + if newfilename: + notes1 += '# SVG change: code: {:04X} name: {}, old: {}, new: {}\n'.format( + orig_point, names[0], filename, newfilename) + filename = newfilename + if filename: + mapping.append((orig_point, dest_point, filename, *names)) + dirname = os.path.dirname(filename) + if dirname in new_names: + new_names.remove(dirname) + continue + + notes2 += '# Icon dropped: code: {:04X} name: {}\n'.format( + orig_point, names[0]) + +index = 0xE700 +taken_codes = set([ e[1] for e in mapping ]) +for iconname in new_names: + filename = suggest_new_filename(iconname) + if not filename: + sys.exit('Can not find svg for "{}"'.format(iconname)) + while index in taken_codes: + index = index + 1 + mapping.append((index - 0x0100, index, filename, iconname)) + taken_codes.add(index) + +with open('mapping', 'w', encoding = 'utf8') as f: + f.write('# Devicons mapping file\n') + f.write('#\n') + f.write('# DEV-code NF-code filename name [alias [...]]\n') + f.write('#\n') + + mapping.sort(key=(lambda x: x[1])) + unique_names = set() + for orig_point, dest_point, filename, *names in mapping: + aliases = get_aliases(names) + for n in aliases: + if n not in unique_names: + unique_names.add(n) + else: + sys.exit('ERROR name duplicate found: {}'.format(n)) + f.write("{:04X} {:04X} {} {}\n".format(orig_point, dest_point, filename, ' '.join(aliases))) + +print(notes1) +print(notes2) diff --git a/src/glyphs/devicons/generate b/src/glyphs/devicons/generate new file mode 100755 index 0000000000..4b9d0a6402 --- /dev/null +++ b/src/glyphs/devicons/generate @@ -0,0 +1,120 @@ +#!/usr/bin/env python3 +# coding=utf8 + +# PREREQUISITES: +# Have a correct and up to date mappings file, updated maybe with analyze +# $ analyze > mapping + +import sys +import os +import re +import subprocess +import fontforge + +# Double-quotes required here, for version-bump.sh: +# version-bump.sh is not working here, need to adjust manually! +version = "3.3.0" + +dev_version = 'v2.16.0' +archive = '{}.tar.gz'.format(dev_version) + +vectorsdir = 'icons' +fontdir = '.' +fontfile = 'devicons.otf' +glyphsetfile = 'i_dev.sh' +glyphsetsdir = '../../../bin/scripts/lib' + +def addIcon(codepoint, name, filename): + """ Add one outline file and rescale/move """ + filename = os.path.join(vectorsdir, filename) + glyph = font.createChar(codepoint, name) + glyph.importOutlines(filename) + xmin, ymin, xmax, ymax = glyph.boundingBox() + glyph.width = int(xmax + xmin) # make left and right bearings equal + glyph.manualHints = True + +def createGlyphInfo(icon_datasets, filepathname, into): + """ Write the glyphinfo file """ + with open(filepathname, 'w', encoding = 'utf8') as f: + f.write(u'#!/usr/bin/env bash\n') + f.write(intro) + f.write(u'# Script Version: (autogenerated)\n') + f.write(u'test -n "$__i_dev_loaded" && return || __i_dev_loaded=1\n') + for _, codepoint, _, *name in icon_datasets: + codepoint = int(codepoint, 16) + f.write(u"i='{}' i_dev_{}=$i\n".format(chr(codepoint), name[0])) + for more_names in name[1:]: + f.write(u" i_dev_{}=$i\n".format(more_names)) + f.write(u'unset i\n') + +print('\nReading mapping file') +mapping = [] +with open('mapping', 'r') as f: + for line in f.readlines(): + line = line.strip() + if line.startswith('#') or len(line) < 1: + continue + mapping.append(tuple(re.split(' +', line.strip()))) +print('Found {} entries'.format(len(mapping))) +mapping.sort(key=(lambda x: x[1])) + +print('Fetching Devicons archive "{}"\n'.format(archive)) +if False and subprocess.call('curl -OL https://github.com/devicons/devicon/archive/refs/tags/' + archive, shell=True): + sys.exit('Error fetching Devicons archive') + +print('\nUnpacking Devicons archive') +if False and subprocess.call('rm -rf devicon-* icons && tar zxf ' + archive + \ + ' && mv devicon-*/icons . && rm -rf v*.tar.gz', shell=True): + sys.exit('Error unpacking archive') + +print('\nMixing Vorillaz Devicons in') +if subprocess.call('cp -r vorillaz icons', shell=True): + sys.exit('Error mixing ...') + + +svg_dirs = os.listdir(vectorsdir) +svgs = [] +for d in svg_dirs: + svgs += os.listdir(vectorsdir + '/' + d) +print('Found {} svgs'.format(len(svgs))) + +font = fontforge.font() +font.fontname = 'Devicons-NerdFont-Regular' +font.fullname = 'Devicons Nerd Font Regular' +font.familyname = 'Devicons Nerd Font' +font.ascent = 1000 +font.descent = 200 +font.encoding = 'UnicodeFull' + +# Add valid space glyph to avoid "unknown character" box on IE11 +glyph = font.createChar(32) +glyph.width = 200 + +font.sfntRevision = None # Auto-set (refreshed) by fontforge +font.version = version +font.copyright = 'Fonticons, Inc' +font.appendSFNTName('English (US)', 'Version', archive + '; ' + version) +font.appendSFNTName('English (US)', 'Vendor URL', 'https://github.com/ryanoasis/nerd-fonts') +font.appendSFNTName('English (US)', 'Copyright', 'See https://github.com/devicons/devicon') + +for _, codepoint, file, *names in mapping: + codepoint = int(codepoint, 16) + addIcon(codepoint, names[0], file) + +num_icons = len(mapping) + +print('Generating {} with {} glyphs'.format(fontfile, num_icons)) +font.ascent = 1100 +font.descent = 300 +font.generate(os.path.join(fontdir, fontfile), flags=("no-FFTM-table",)) + +codepoints = [ int(p, 16) for _, p, *_ in mapping ] +aliases = [ len(n) - 1 for _, _, _, *n in mapping ] +intro = u'# Devicons (version {}, {} icons, {} aliases)\n'.format(dev_version, num_icons, sum(aliases)) +intro += u'# Does not include all icons of the release\n' +intro += u'# Codepoints: {:X}-{:X} with gaps\n'.format(min(codepoints), max(codepoints)) +intro += u'# Nerd Fonts Version: {}\n'.format(version) + +print('Generating GlyphInfo {}'.format(glyphsetfile)) +createGlyphInfo(mapping, os.path.join(glyphsetsdir, glyphsetfile), intro) +print('Finished') diff --git a/src/glyphs/devicons/mapping b/src/glyphs/devicons/mapping new file mode 100644 index 0000000000..a654e688a3 --- /dev/null +++ b/src/glyphs/devicons/mapping @@ -0,0 +1,202 @@ +# Devicons mapping file +# +# DEV-code NF-code filename name... +# +E600 E700 vorillaz/bing_small.svg bing_small +E601 E701 vorillaz/css_tricks.svg css_tricks +E602 E702 vorillaz/git.svg git +E603 E703 vorillaz/bitbucket.svg bitbucket +E604 E704 vorillaz/mysql.svg mysql +E605 E705 vorillaz/streamline.svg streamline +E606 E706 vorillaz/database.svg database +E607 E707 vorillaz/dropbox.svg dropbox +E608 E708 vorillaz/github_alt.svg github_alt +E609 E709 vorillaz/github_badge.svg github_badge +E60A E70A vorillaz/github.svg github +E60B E70B vorillaz/wordpress.svg wordpress +E60C E70C vorillaz/visualstudio.svg visualstudio +E60D E70D vorillaz/jekyll_small.svg jekyll_small +E60E E70E vorillaz/android.svg android +E60F E70F vorillaz/windows.svg windows +E610 E710 vorillaz/stackoverflow.svg stackoverflow +E611 E711 vorillaz/apple.svg apple +E612 E712 vorillaz/linux.svg linux +E613 E713 vorillaz/appstore.svg appstore +E614 E714 vorillaz/ghost_small.svg ghost_small +E615 E715 vorillaz/yahoo.svg yahoo +E616 E716 vorillaz/codepen.svg codepen +E617 E717 vorillaz/github_full.svg github_full +E618 E718 vorillaz/nodejs_small.svg nodejs_small +E619 E719 vorillaz/nodejs.svg nodejs +E61A E71A vorillaz/hackernews.svg hackernews +E61B E71B vorillaz/ember.svg ember +E61C E71C vorillaz/dojo.svg dojo +E61D E71D vorillaz/django.svg django +E61E E71E vorillaz/npm.svg npm +E61F E71F vorillaz/ghost.svg ghost +E620 E720 vorillaz/modernizr.svg modernizr +E621 E721 vorillaz/unity_small.svg unity_small +E622 E722 vorillaz/rasberry_pi.svg raspberry_pi +E623 E723 vorillaz/blackberry.svg blackberry +E624 E724 vorillaz/go.svg go +E625 E725 vorillaz/git_branch.svg git_branch +E626 E726 vorillaz/git_pull_request.svg git_pull_request +E627 E727 vorillaz/git_merge.svg git_merge +E628 E728 vorillaz/git_compare.svg git_compare +E629 E729 vorillaz/git_commit.svg git_commit +E62A E72A vorillaz/cssdeck.svg cssdeck +E62B E72B vorillaz/yahoo_small.svg yahoo_small +E62C E72C vorillaz/techcrunch.svg techcrunch +E62D E72D vorillaz/smashing_magazine.svg smashing_magazine +E62E E72E vorillaz/netmagazine.svg netmagazine +E62F E72F vorillaz/codrops.svg codrops +E630 E730 vorillaz/phonegap.svg phonegap +E631 E731 vorillaz/google_drive.svg google_drive +E632 E732 vorillaz/html5_multimedia.svg html5_multimedia +E633 E733 vorillaz/html5_device_access.svg html5_device_access +E634 E734 vorillaz/html5_connectivity.svg html5_connectivity +E635 E735 vorillaz/html5_3d_effects.svg html5_3d_effects +E636 E736 vorillaz/html5.svg html5 +E637 E737 vorillaz/scala.svg scala +E638 E738 vorillaz/java.svg java +E639 E739 vorillaz/ruby.svg ruby +E63A E73A vorillaz/ubuntu.svg ubuntu +E63B E73B vorillaz/ruby_on_rails.svg ruby_on_rails +E63C E73C vorillaz/python.svg python +E63D E73D vorillaz/php.svg php +E63E E73E vorillaz/markdown.svg markdown +E63F E73F vorillaz/laravel.svg laravel +E640 E740 vorillaz/magento.svg magento +E641 E741 vorillaz/joomla.svg joomla +E642 E742 vorillaz/drupal.svg drupal +E643 E743 vorillaz/chrome.svg chrome +E644 E744 vorillaz/ie.svg ie +E645 E745 vorillaz/firefox.svg firefox +E646 E746 vorillaz/opera.svg opera +E647 E747 vorillaz/bootstrap.svg bootstrap +E648 E748 vorillaz/safari.svg safari +E649 E749 vorillaz/css3.svg css3 +E64A E74A vorillaz/css3_full.svg css3_full +E64B E74B vorillaz/sass.svg sass +E64C E74C vorillaz/grunt.svg grunt +E64D E74D vorillaz/bower.svg bower +E64E E74E vorillaz/javascript.svg javascript +E64F E74F vorillaz/javascript_shield.svg javascript_shield +E650 E750 vorillaz/jquery.svg jquery +E651 E751 vorillaz/coffeescript.svg coffeescript +E652 E752 vorillaz/backbone.svg backbone +E653 E753 vorillaz/angular.svg angular +E654 E754 vorillaz/jquery_ui.svg jquery_ui +E655 E755 vorillaz/swift.svg swift +E656 E756 vorillaz/symfony.svg symfony +E657 E757 vorillaz/symfony_badge.svg symfony_badge +E658 E758 vorillaz/less.svg less +E659 E759 vorillaz/stylus.svg stylus +E65A E75A vorillaz/trello.svg trello +E65B E75B vorillaz/atlassian.svg atlassian +E65C E75C vorillaz/jira.svg jira +E65D E75D vorillaz/envato.svg envato +E65E E75E vorillaz/snap_svg.svg snap_svg +E65F E75F vorillaz/raphael.svg raphael +E660 E760 vorillaz/chart.svg chart +E661 E761 vorillaz/compass.svg compass +E662 E762 vorillaz/onedrive.svg onedrive +E663 E763 vorillaz/gulp.svg gulp +E664 E764 vorillaz/atom.svg atom +E665 E765 vorillaz/cisco.svg cisco +E666 E766 vorillaz/nancy.svg nancy +E667 E767 vorillaz/jenkins.svg jenkins +E668 E768 vorillaz/clojure.svg clojure +E669 E769 vorillaz/perl.svg perl +E66A E76A vorillaz/clojure_alt.svg clojure_alt +E66B E76B vorillaz/celluloid.svg celluloid +E66C E76C vorillaz/w3c.svg w3c +E66D E76D vorillaz/redis.svg redis +E66E E76E vorillaz/postgresql.svg postgresql +E66F E76F vorillaz/webplatform.svg webplatform +E670 E770 vorillaz/requirejs.svg requirejs +E671 E771 vorillaz/opensource.svg opensource +E672 E772 vorillaz/typo3.svg typo3 +E673 E773 vorillaz/uikit.svg uikit +E674 E774 vorillaz/doctrine.svg doctrine +E675 E775 vorillaz/groovy.svg groovy +E676 E776 vorillaz/nginx.svg nginx +E677 E777 vorillaz/haskell.svg haskell +E678 E778 vorillaz/zend.svg zend +E679 E779 vorillaz/gnu.svg gnu +E67A E77A vorillaz/yeoman.svg yeoman +E67B E77B vorillaz/heroku.svg heroku +E67C E77C vorillaz/msql_server.svg msql_server +E67D E77D vorillaz/debian.svg debian +E67E E77E vorillaz/travis.svg travis +E67F E77F vorillaz/dotnet.svg dotnet +E680 E780 vorillaz/codeigniter.svg codeigniter +E681 E781 vorillaz/javascript_badge.svg javascript_badge +E682 E782 vorillaz/yii.svg yii +E683 E783 vorillaz/composer.svg composer +E684 E784 vorillaz/krakenjs_badge.svg krakenjs_badge +E685 E785 vorillaz/krakenjs.svg krakenjs +E686 E786 vorillaz/mozilla.svg mozilla +E687 E787 vorillaz/firebase.svg firebase +E688 E788 vorillaz/sizzlejs.svg sizzlejs +E689 E789 vorillaz/creativecommons.svg creativecommons +E68A E78A vorillaz/creativecommons_badge.svg creativecommons_badge +E68B E78B vorillaz/mitlicence.svg mitlicence +E68C E78C vorillaz/senchatouch.svg senchatouch +E68D E78D vorillaz/bugsense.svg bugsense +E68E E78E vorillaz/extjs.svg extjs +E68F E78F vorillaz/mootools_badge.svg mootools_badge +E690 E790 vorillaz/mootools.svg mootools +E691 E791 vorillaz/ruby_rough.svg ruby_rough +E692 E792 vorillaz/komodo.svg komodo +E693 E793 vorillaz/coda.svg coda +E694 E794 vorillaz/bintray.svg bintray +E695 E795 vorillaz/terminal.svg terminal +E696 E796 vorillaz/code.svg code +E697 E797 vorillaz/responsive.svg responsive +E698 E798 vorillaz/dart.svg dart +E699 E799 vorillaz/aptana.svg aptana +E69A E79A vorillaz/mailchimp.svg mailchimp +E69B E79B vorillaz/netbeans.svg netbeans +E69C E79C vorillaz/dreamweaver.svg dreamweaver +E69D E79D vorillaz/brackets.svg brackets +E69E E79E vorillaz/eclipse.svg eclipse +E69F E79F vorillaz/cloud9.svg cloud9 +E6A0 E7A0 vorillaz/scrum.svg scrum +E6A1 E7A1 vorillaz/prolog.svg prolog +E6A2 E7A2 vorillaz/terminal_badge.svg terminal_badge +E6A3 E7A3 vorillaz/code_badge.svg code_badge +E6A4 E7A4 vorillaz/mongodb.svg mongodb +E6A5 E7A5 vorillaz/meteor.svg meteor +E6A6 E7A6 vorillaz/meteorfull.svg meteorfull +E6A7 E7A7 vorillaz/fsharp.svg fsharp +E6A8 E7A8 vorillaz/rust.svg rust +E6A9 E7A9 vorillaz/ionic.svg ionic +E6AA E7AA vorillaz/sublime.svg sublime +E6AB E7AB vorillaz/appcelerator.svg appcelerator +E6AC E7AC vorillaz/asterisk.svg asterisk +E6AD E7AD vorillaz/aws.svg aws +E6AE E7AE vorillaz/digital_ocean.svg digital_ocean +E6AF E7AF vorillaz/dlang.svg dlang +E6B0 E7B0 vorillaz/docker.svg docker +E6B1 E7B1 vorillaz/erlang.svg erlang +E6B2 E7B2 vorillaz/google_cloud_platform.svg google_cloud_platform +E6B3 E7B3 vorillaz/grails.svg grails +E6B4 E7B4 vorillaz/illustrator.svg illustrator +E6B5 E7B5 vorillaz/intellij.svg intellij +E6B6 E7B6 vorillaz/materializecss.svg materializecss +E6B7 E7B7 vorillaz/openshift.svg openshift +E6B8 E7B8 vorillaz/photoshop.svg photoshop +E6B9 E7B9 vorillaz/rackspace.svg rackspace +E6BA E7BA vorillaz/react.svg react +E6BB E7BB vorillaz/redhat.svg redhat +E6BC E7BC vorillaz/scriptcs.svg scriptcs +E6BD E7BD vorillaz/-.svg - +E6BE E7BE vorillaz/-.svg - +E6BF E7BF vorillaz/-.svg - +E6C0 E7C0 vorillaz/-.svg - +E6C1 E7C1 vorillaz/-.svg - +E6C2 E7C2 vorillaz/-.svg - +E6C3 E7C3 vorillaz/-.svg - +E6C4 E7C4 vorillaz/sqllite.svg sqlite +E6C5 E7C5 vorillaz/vim.svg vim