Projects About AlBasmala
build status

Badge Links

Article image
  

Ξ  

⭐ The code lives at github.com/alhassy/org-special-block-extras —star it, or discuss it there!

Badges provide a quick and colourful summary of key features of a project, such as whether it's maintained, its license, and if it's documented.

badges.png

Figure 1: An Emacs interface to https://shields.io/

As people who are passionate about writing great code we display "badges" in our code repositories to signal to fellow developers that we set ourselves high standards for the code we write, think of them as the software-equivalent of the brand on your jeans or other reliable product. — repo-badges

﴾What You Write﴿
What are badges?

badge:Let_me_google_that|for_you!|orange|https://lmgtfy.app/?q=badge+shields.io&iie=1|Elixir

or

[[badge: Let me google that | for you! |orange|
         https://lmgtfy.app/?q=badge+shields.io&iie=1 |Elixir]]

or

badge:Let_me_*not*_google_that|for_you
﴾What You Get﴿

What are badges?

or

or

Notice that the orange badge points to a URL and so is clickable, whereas the green one does not point to a URL and so is not clickable.

Automated Tests

Let's have some sanity tests…

(deftest "It works when all 5 arguments are provided"
  [badge]
  (⇝ (⟰ "badge:Let_me_google_that|for_you!|orange|https://lmgtfy.app/?q=badge+shields.io&iie=1|Elixir")
     "<a href=\"https://lmgtfy.app/?q=badge+shields.io&iie=1\">"
     "<img src=\"https://img.shields.io/badge/Let_me_google_that-for_you%21-orange?logo=Elixir\"></a>"))

(deftest "It works when we use [[link]] syntax with generous spaces and newlines"
  [badge]
  (⇝ (⟰ "[[badge: Let me google that | for you! | orange |
         https://lmgtfy.app/?q=badge+shields.io&iie=1|Elixir]]")

     "<a href=\"https://lmgtfy.app/?q=badge+shields.io&iie=1\">"
     (* anything)
     "<img src=\"https://img.shields.io/badge/Let%20me%20google%20that-for%20you%21-orange?logo=Elixir\">"))

(deftest "It works when only the first 2 arguments are provided; asterisks are passed unaltered into the first argument"
  [badge]
  (⇝ (⟰ "badge:Let_me_*not*_google_that|for_you")
     "<img src=\"https://img.shields.io/badge/Let_me_%2Anot%2A_google_that-for_you-nil?logo=nil\">"))

(deftest "It works when all 5 arguments are provided - URL ‘here’ makes it a local link"
  [badge]
  (⇝ (⟰ "badge:key|value|informational||Elixir")
     "<a id=\"key\" href=\"#key\">"
     "<img src=\"https://img.shields.io/badge/key-value-informational?logo=Elixir\"></a>"))

(deftest "We can use spaces, commas, dashes, and percentage symbols in the first argument"
  [badge]
  (⇝ (⟰ "badge:example_with_spaces,_-,_and_%|points_right_here|orange")
     "<a id=\"example_with_spaces,_-,_and_%\" href=\"#example_with_spaces,_-,_and_%\">"
     "<img src=\"https://img.shields.io/badge/example_with_spaces%2C_--%2C_and_%25-points_right_here-orange?logo=nil\"></a>"))

(deftest "It works when only first 2 arguments are given: Default colour & logo are green & no logo shown"
  [badge]
  (⇝ (⟰ "badge:key|value")
     "<img src=\"https://img.shields.io/badge/key-value-nil?logo=nil\">"))

(deftest "When only a key is provided, the value slot is shown as an empty green stub"
  [badge]
  (⇝ (⟰ "badge:key")
     "<img src=\"https://img.shields.io/badge/key--nil?logo=nil\">"))

(deftest "When only a value is provided, only the value is shown in a default green ---no stub for the missing key, yay"
  [badge]
  (⇝ (⟰ "badge:|value")
        "<img src=\"https://img.shields.io/badge/-value-nil?logo=nil\">"))


(deftest "It's only a green stub when provided with an empty key and empty value"
  [badge]
  (⇝ (⟰ "badge:||green")
     "<img src=\"https://img.shields.io/badge/--green?logo=nil\">"))

(deftest "It's only a green stub when we use a totally [[badge:]]"
  [badge]
  (⇝ (⟰ "[[badge:]]")
     "<img src=\"https://img.shields.io/badge/--nil?logo=nil\">"))

1. Example Badges

The general syntax is as follows, with only the first 2 are mandatory, with the colour defaulting to green, and the url and logo both to nil. We can thus have badge:label|message

  • ⇐ <<key>> badge:key|value|informational||Elixir
    • Standard template; Org's own target beside it is a permalink to the current location, named #key —click on it and look at your browser's URL ;-)
  • ⇐ badge:example_with_spaces,_-,_and_%|points_right_here|orange
  • ⇐ badge:key|value.
  • ⇐ badge:empty_value||informational
  • ⇐ badge:|value
  • ⇐ badge:||green ( No key; nor value! )

    Also: ⇐ [[badge:]].

General Syntax

badge:your_key|its_neato_value|some_url|a_logo_as_shown_below

[[badge: your key | its neato value | some url | a logo as shown below]]

reddit-subscribe-to:exact-name-of-a-subreddit

github-stars:user-name/repository-name

github-watchers:user-name/repository-name

github-forks:user-name/repository-name

github-followers:user-name

tweet:url

For now, only badge: badges redirect to their URL, if any, upon a user's click. Within Emacs, hovering over a badge displays a tooltip indicating which values corresponds to which badge fields.

You can make your own badge types with org-make-badge.

org-make-badge

The implementation is a bit lengthy since it attempts to capture a useful portion of the shilelds.io badge interface.

(cl-defmacro org-make-badge
  (name &optional social-shields-name social-url social-shields-url )
  "Make a link NAME whose export is presented as an SVG badge.

If the link is intend to be a social badge, then, adhering to
shield.io conventions, the appropriate SOCIAL-SHIELDS-NAME must
be given.

The SOCIAL-URL is a URL that the badge points to and it should
have a single ‘%s’ where the link label argument will go.

Some social badges have a uniform URL, but otherwise, such as
twitter, deviate and so need their own SOCIAL-SHIELDS-URL,
which has a single ‘%s’ for the link's label argument.

----------------------------------------------------------------------

E.g., to create a badge named “go”:

     (org-make-badge \"go\")

Then the following exports nicely from an Org file:

     go:key|value|blue||gnu-emacs"
  `(org-deflink ,(intern name) (label &optional _description backend)
    "Export a Shields.io badge, with general Syntax:  badge:key|value|colour|url|logo.
Precise details for each argument are shown in the Emacs tooltip for this badge."
    [:display 'full
     :follow (--> (s-split "|" path)
               (or (nth 3 it) label)
               (browse-url it))
    :help-echo
      (-let [ (key value color url logo)  (mapcar #'s-trim (s-split "|" label)) ]
        (lf-string "${label}
                    \nGeneral Syntax:  badge:key|value|colour|url|logo
                           Key    : ${key}
                           Value  : ${(or value \"\")}
                           Colour : ${(or color \"green\")}
                           URL    : ${(or url \"\")}
                           Logo   : ${(or logo \"\")}

                    This results in an SVG badge “[key∣value]”, where the ‘key’
                    is coloured grey and the ‘value’ is coloured ‘color’;
                    for the HTML backend, and otherwise are silently omitted.
                    Descriptions are ignored; i.e., ‘[[badge:label][description]]’
                    is the same as ‘[[badge:label]]’.

                    ► ‘key’ and ‘value’ have their underscores interpreted as spaces.
                       ⇒ ‘__’ is interpreted as an underscore;
                         Of course, you can write ‘<badge: ⋯>’, then ‘⋯’ may have multiword, spaced, content.
                       ⇒ ‘|’ is not a valid substring, but ‘-, %, ?’ are okay.

                    ► ‘|color|url|logo’ are optional;
                       ⇒ If ‘url’ is not present, the resulting badge is not a hyperlink.
                       ⇒ if ‘url’ is ‘here’ then we have a local link;
                          i.e., the resulting badge behaves like <<key>>.
                       ⇒ ‘color’ may be: ‘brightgreen’ or ‘success’,
                                         ‘red’         or ‘important’,
                                         ‘orange’      or ‘critical’,
                                         ‘lightgrey’   or ‘inactive’,
                                         ‘blue’        or ‘informational’,
                         or ‘green’, ‘yellowgreen’, ‘yellow’, ‘blueviolet’, ‘ff69b4’, etc.
                         Consult https://htmlcolorcodes.com/ to see the HEX codes of other colours.
                       ⇒ ‘logo’ examples and how they look can be found at
                          https://alhassy.com/org-special-block-extras#Example-Badge-Icons

                   See also: https://alhassy.com/org-special-block-extras#Common-Project-Badges"))]

    ;; :export #'org--link--badge
    (if (equal backend 'latex) ""
      (-let [ (key value color url logo)  (mapcar #'s-trim (s-split "|" label)) ]
        (format
         (pcase ,(if social-shields-name `(format ,social-url label) 'url)
           ("here" (format "<a id=\"%s\" href=\"#%s\">%%s</a>" (s-replace "%" "%%" key) (s-replace "%" "%%" key)))
           (""      "%s") ;; e.g., badge:key|value|color||logo
           ('nil    "%s") ;; e.g., badge:key|value|color
           (_ (format "<a href=\"%s\">%%s</a>"
                      (s-replace "%" "%%"
                                 ,(if social-shields-name
                                      `(format ,social-url label)
                                    'url)))))
         ,(if social-shields-name
              (if social-shields-url
                  `(format ,social-shields-url label)
                `(format "<img src=\"https://img.shields.io/%s/%s?style=social\">"
                         ,social-shields-name label))
            '(format "<img src=\"https://img.shields.io/badge/%s-%s-%s?logo=%s\">"
                     (url-hexify-string (s-replace "-" "--" key))
                     (url-hexify-string (s-replace "-" "--" (or value "")))
                     color
                     logo)))))))

Notice that we can have special %-HTML characters in URLs; e.g., <badge:my key|my value| my colour|https://www.google.com/search?q=hello%20world|gnu-emacs> ⇒ .

Example: Derived Reddit/Github/Twitter social badges

For example, a super simple ‘badge’ link type

(org-make-badge "badge")

A more involved example.

;; Since we're invoking a macro, the twitter-excitement is used lazily; i.e.,
;; consulted when needed instead of being evaluated once.
(defvar org-link-twitter-excitement
  "This looks super neat (•̀ᴗ•́)و:"
  "The string prefixing the URL being shared.")

(org-make-badge
 "tweet"
 "twitter/url?=url="
 (format
   "https://twitter.com/intent/tweet?text=%s:&url=%%s"
   org-link-twitter-excitement)
 "<img src=\"https://img.shields.io/twitter/url?url=%s\">"
               )

A few more in one, convoluted, go.

;; MA: I don't think this is ideal for long-term maintainability, see ‘:OLD’ below.
(cl-loop for (social url name)
         in '(("reddit/subreddit-subscribers" "https://www.reddit.com/r/%s" "reddit")
             ("github" "https://www.github.com/%s")
             ("github/stars" "https://github.com/%s")      ; Its Star button; /stars is no page
             ("github/watchers" "https://github.com/%s")   ; Its Watch button; /watchers needs a login
             ("github/followers" "https://www.github.com/%s?tab=followers")
             ("github/forks" "https://www.github.com/%s/fork"))
         for name′ = (or name (s-replace "/" "-" social))
         do (eval `(org-make-badge ,name′ ,social ,url)))

Here are some examples.

  • Things I like:
  • Info about my cheatsheets:
  • My profile:

2. Example Colours

﴾What You Write﴿
+ badge:|red|red badge:|critical|critical
+ badge:|blue|blue badge:|informational|informational
+ badge:|brightgreen|brightgreen badge:|success|success
+ badge:|orange|orange badge:|important|important
+ badge:|lightgrey|lightgrey badge:|inactive|inactive
+ badge:|green|green
+ badge:|yellowgreen|yellowgreen
+ badge:|yellow|yellow
+ badge:|blueviolet|blueviolet
+ badge:|ff69b4|ff69b4
+ badge:|9cf|9cf
+ ...

Consult https://htmlcolorcodes.com/ to see the HEX code of any other colour you
wish to use; e.g., badge:|1d8348|1d8348
﴾What You Get﴿
  • …

Consult https://htmlcolorcodes.com/ to see the HEX code of any other colour you wish to use; e.g.,

3. Example Badge Icons

Here are a few free SVG icons for popular brands from https://simpleicons.org/.

To use any of the names below, just write, say, badge:||grey||SVG-NAME-HERE.

“Fire”
  • Elixir
  • tinder
  • codeigniter
  • prometheus
  • sparkpost

“Messaging”
  • quip
  • WeChat
  • google-hangouts
  • hackhands
  • google-messages
  • Slack

“Emacs”
  • gnu-emacs
  • spacemacs
  • vim
  • neovim
  • gnu
  • github
  • acm
  • wikipedia
  • microsoft-excel
  • microsoft-word
  • dropbox
  • google-scholar
  • google
  • google-translate
  • ghost
  • helm
  • apache-openoffice
  • buffer
  • adobe-fonts
  • google-calendar

“Social”
  • google-cast
  • youtube
  • discord
  • facebook
  • google-hangouts
  • whatsapp
  • skype
  • reddit
  • stack-overflow
  • stack-exchange
  • linkedin
  • twitter
  • jabber

“Lightbulb”
  • lighthouse
  • google-keep
  • minds

“Programming”
  • git
  • ruby
  • scala
  • OCaml
  • javascript
  • gnu-bash
  • powershell
  • LaTeX
  • java
  • kotlin
  • haskell
  • coffeescript
  • purescript
  • rust
  • typescript
  • css3
  • python
  • c
  • clojure
  • lua
  • adobe-acrobat-reader
  • perl

“Miscellaneous”
  • read-the-docs
  • buy-me-a-coffee
  • gimp
  • mega
  • nintendo-3ds
  • paypal
  • pinboard
  • mocha
  • Gitea
  • instacart
  • openStreetMap
  • amazon
  • svg
  • rss
  • swagger
  • pastebin
  • skyliner
  • iTunes
  • gulp
  • leaflet
  • youtube-gaming
  • GIMP
  • atom

4. Common Project Badges —with copyable source

  • src badge:Emacs|23/26/28|green|https://www.gnu.org/software/emacs|gnu-emacs
  • src badge:Org|9.3.6|blue|https://orgmode.org|gnu
  • src [[badge:org-special-block-extras|1.0|informational|https://alhassy.com/org-special-block-extras|Gnu-Emacs][org-special-block-extras badge]]
  • src [[badge:melpa|pending|critical|https://github.com/alhassy/emacs.d#use-package-the-start-of-initel|github][melpa badge]]
  • src [[badge:docs|literate|success|https://github.com/alhassy/emacs.d#what-does-literate-programming-look-like|read-the-docs][read-the-docs badge]]
    src badge:wiki|github|informational||wikipedia
  • src badge:code_coverage|88%|green||codecov
    src badge:build|passing|success||azure-pipelines
  • src badge:author|musa_al-hassy|purple|https://alhassy.github.io/|nintendo-3ds
  • src badge:author|musa_al-hassy|purple|https://alhassy.github.io/|gimp
  • src [[badge:license|GNU_3|informational|https://www.gnu.org/licenses/gpl-3.0.en.html|read-the-docs][gnu 3 license badge]]
  • src badge:issue_tracking|github|informational||github
  • src badge:help_forum|discourse|informational||discourse
  • src badge:social_chat|gitter|informational|https://gitter.im/explore|gitter
  • src badge:Maintained?|yes|success
    src badge:Maintained?|no|critical
    src badge:No_Maintenance_Intended|×|critical|http://unmaintained.tech/
  • src badge:website|up|success
    src badge:website|down|critical
  • src badge:Ask_me|anything|1abc9c
    src badge:contributions|welcome|green|https://github.com/alhassy/org-special-block-extras/issues
  • src badge:Made_with|Python,_LaTeX,_MathJax,_and_Emacs_Org-mode|1f425

5. Next Steps

Going forward, it would be desirable to provide non-whitespace alternatives for the LaTeX backend.

[Author: That is why no examples are shown in the PDF ]

It may be useful to colour the |-separated fields of a badge link.


Generated by Emacs and Org-mode (•̀ᴗ•́)و
Creative Commons License
Life & Computing Science by Musa Al-hassy is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License