Liking cljdoc? Tell your friends :D

bling

Helps you quickly get rich text into your console printing.

bling on Clojars


Features

  • Works great for both Clojure and ClojureScript.

  • Supports both terminal emulators and browser consoles.

  • Simple, accessibility-focused, 8-color pallette.

  • All colors provide reasonable contrast on both light and dark backgrounds.

  • Simple and intuitive hiccup-like markup syntax.

  • Sensible templates for callouts warning and error callouts.


Setup

Add as a dependency to your project:

[io.github.paintparty/bling "0.1.0"]

Import into your namespace:

(ns myns.core
  (:require
    [bling.core :refer [bling callout point-of-interest]]))

;; In ClojureScript, you may also want :refer bling.core/print-bling.

Basic Usage

Note that if you are reading this on github in a light-mode theme, the dark-mode samples in the sections below will appear to have lower contrast than they actually do if you were viewing them in dark-mode.

bling.core/bling takes any number of arguments and returns a string of text decorated with tags for colorization, italics, and boldness:

(println (bling [:bold "bold"]
                 ", "
                 [:italic "italic"]
                 ", or "
                 [:blue "colored"]))


In ClojureScript, bling returns a js object that needs to be printed like this:
(.apply js/console.log js/console (goog.object/get o "consoleArray")).

To avoid typing all this out, you can use bling.core/print-bling to print the array returned from bling:

(print-bling (bling [:bold "bold"]
                        ", "
                        [:italic "italic"]
                        ", or "
                        [:blue "colored"]))

By default, in ClojureScript, bling.core/print-bling prints with js/console.log. However, if you would like to print with either js.console/warn, or js/console.error, you can pass either as a second argument.

(print-bling (bling [:bold "bold"]
                        ", "
                        [:italic "italic"]
                        ", or "
                        [:blue "colored"])
                js/console.warn)

Combo styles

You can add multiple decorations with hiccup-style tags (a keyword with dot separators). The order of the things separated by dots doesn't matter.

(println (bling [:bold.italic "bold & italic"]
                 ", "
                 [:italic.blue "italic & colored"]
                 ", "
                 [:bold.italic.white.blue-bg "bold & italic & colored & colored-bg"]))


The bling pallette

Eight carefully selected colors, from the xterm range 16-255, are available for use (shown in bold). All of these colors should display consistantly across most consoles on the end-user side. Don't expect all of the colors to pass the strictest APCA contrast criterion, but you can be sure of reasonably visibility on both light and dark backgrounds:

(println (bling [:bold.red "Red"]
                 ", "
                 [:bold.yellow "Yellow"]
                 ", "
                 [:bold.green "Green"]
                 ", "
                 [:bold.blue "Blue"]
                 ", "
                 [:bold.magenta "Magenta"]
                 ", "
                 [:bold.gray "Gray"]
                 ", "
                 [:bold.black "Black"]
                 ", "
                 [:bold.white "White"] ))


Color aliases

You can use the following semantic aliases for some colors (shown in bold):

(println (bling [:bold.negative "Negative"]
                 ", "
                 [:bold.error "Error"]
                 ", "
                 [:bold.warning "Warning"]
                 ", "
                 [:bold.positive "Positive"]
                 ", "
                 [:bold.info "Info"]
                 ", "
                 [:bold.subtle "Subtle"]
                 ", "
                 [:bold.neutral "Neutral"] ))


You can also pass a map (instead of a hiccup-style tag) to style the text:

(bling [{:color            :green
         :background-color :black
         :font-style       :italic
         :font-weight      :bold}
         "Negative"])

Note that all the arguments to bling.core/bling must satisfy this predicate:

(every? (fn [x]
          (or (and (vector? x)
                   (= 2 (count x))
                   (-> x
                       (nth 0)
                       (maybe #(or (keyword? %)
                                   (map? %)))))
              (not (coll? x))))
        args)

In other words, every one of the arguments to bling.core/bling must be either:

  • A two-element vector, with the first element being a keyword or map.
  • A value which is not a collection.

If you want to print [1 2 3] in red, you will need to stringify the vector:

(bling [:red (str [1 2 3])])


Printing formatted blocks to the console

bling.core/callout will print a message "block" to the console with a colored bounding border in the inline-start position.

(callout {:type :info}
         "Example callout, with :type of :info")

(callout {:type  :info
          :label "My custom label"}
         "Example callout, with :type of :info and custom :label")

(callout {:type :warning}
         "Example callout, with :type of :warning")

(callout {:type :error}
         "Example callout, with :type of :error")

(callout {:type  :positive
          :label "SUCCESS!"}
         "Example callout, with :type of :positive, and custom :label")

(callout {:type :subtle}
         "Example callout, with :type of :subtle (or :gray)")

(callout {:type :magenta}
         "Example callout, with :type of :magenta")

(callout "Example callout, default")

The above calls would render the following in your favorite terminal emulator:

bling.core/callout takes one or two arguments. If two arguments are supplied, the first should be a map with 0 or more of following entries:

KeyPredDescription
:labelany?
Labels the callout. In a terminal emulator context, the value will be cast to a string. In a browser context, the label can be an instance of bling.core/Enriched, or any other value (which will be cast to a string).
In the case of a callout :type of :warning, :error, or :info, the value of the label will default to "WARNING", "ERROR", or "INFO", respectively.

:typekeyword? or string?
Controls the color of the border and label.
Should be one of: :error, :warning , :info , :positive, or :subtle.
Can also be any one of the pallete colors such as :magenta, :green, :negative, :neutral, etc.

:border-weightkeyword? or string?
Controls the weight of the border. Can be one of :medium, :heavy, or :light. Defaults to :light, which renders default border with standard unicode, single-line box-drawing character.

:padding-topint?
Amount of padding (in lines) at top of callout (inside callout block).
Defaults to 0.

:padding-bottomint?
Amount of padding (in lines) at bottom of callout (inside callout block).
Defaults to 0. In browser console, defaults to 1 in the case of callouts of type :warning or :error.

:padding-leftint?
Amount of padding (in lines) at left of callout (inside callout block).
In console emulator, defaults to 1 when :border-weight is :light, and 2 when :border-weight is :medium or :heavy. In browser console, defaults to 0.

:margin-topint?
Amount of margin (in lines) at top of callout (outside callout block).
Defaults to 1. Only applies to terminal emulator printing.

:margin-bottomint?
Amount of margin (in lines) at bottom of callout (outside callout block).
Defaults to 0. Only applies to terminal emulator printing.

:data?boolean?
Returns a data representation of result instead of printing it.



Templates for errors and warnings

bling.core/callout, paired with bling.core/point-of-interest is perfect for creating your own custom error or warning messages.

Here is an example of creating a custom callout for an error message. You must provide the relevant :file, :line, :column, and :form values.

(defn example-custom-callout
  [{:keys [point-of-interest-opts callout-opts]}]
  (let [poi-opts     (merge {:header "Your header of your template goes here."
                             :body   (str "The body of your template goes here."
                                          "\n"
                                          "Another line of copy.")}
                            point-of-interest-opts)
        message      (point-of-interest poi-opts)
        callout-opts (merge callout-opts
                            {:padding-top 1})]
    (callout callout-opts message)))

(example-custom-callout
 {:point-of-interest-opts {:type   :error
                           :file   "example.ns.core"
                           :line   11
                           :column 1
                           :form   '(+ 1 true)}
  :callout-opts           {:type :error}})

The above callout would render like this your terminal emulator:

bling.core/point-of-interest takes a single map with the following options:

KeyPredDescription
:filestring?
File or namespace

:lineinteger?
Line number

:columninteger?
Column number

:formany?
The form to draw attention to. Will be cast to string and truncated at 33 chars

:typekeyword or string?
Controls the color of the squiggly underline. Should be one of: :error :warning, or :neutral. Defaults to :neutral

:headerany?
Typically, a string composed with newlines as desired. In a browser context, can be an instance of bling.core/Enriched (produced by using bling.core/bling)

:bodyany?
Typically, a string composed with newlines as desired. In a browser context, can be an instance of bling.core/Enriched (produced by using bling.core/bling)

:margin-blockint?
Controls the number of blank lines above and below the diagram.
Defaults to 1.



Go heavy

If you want to place more emphasis on your callouts you can pass bling.core/callout a :border-weight option with a value of :medium or :heavy. Here is an example using the example-custom-callout function we defined above:

(example-custom-callout
 {:file          "example.ns.core"
  :line          11
  :column        1
  :form          '(+ 1 true)
  :type          :error
  :border-weight :heavy})

Example of a value of :medium for :border-weight:

(example-custom-callout
 {:file          "example.ns.core"
  :line          11
  :column        1
  :form          '(+ 1 true)
  :type          :error
  :border-weight :medium})

More callout examples of :heavy for :border-weight:

More callout examples of :medium for :border-weight:


Status / Roadmap

Alpha, subject to change. Issues welcome, see contributing.


Contributing

Issues for bugs, improvements, or features are very welcome. Please file an issue for discussion before starting or issuing a PR.



Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close