Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert integer to hex in SASS

In lieu of something like the Map data structure that Chris Eppstein mentions as a work in progress for SASS, I'm trying to achieve something similar - mapping a string to a corresponding hex value, which will be used to specify a unicode character for CSS content property. (I'm trying to refactor some font icon SASS code.)

At the moment I have something rudimentary like:

/*icon1  -->  \F000
  icon2  -->  \F001
  icon3  -->  \F002*/

@function u-char($name) {
    @if $name == icon1 {
        @return "000";
    } @else if $name == icon2 {
        @return "001";
    } @else if $name == icon3 {
        @return "001";
    }
}

@mixin icon-class($name) {
    ...
    content: "\f#{u-char($name)}";
    ...
}

But I'm actually trying to map a large number of characters, so this approach is arduous. I was hoping to be able to do something like:

@function u-char($name) {
    $i: 0;
    $itemList: item1, item2, item3;

    @each $currItem in $itemList {
        @if $name == item1 {
            @return i-to-hex-str($i);
        }
        $i: $i + 1;
    }
}

Is there anything that does and integer to hex string conversion in SASS? Is there another elegant way around this?

like image 618
Prembo Avatar asked Apr 12 '13 00:04

Prembo


3 Answers

To answer the last question in your post, "Is there anything that does an integer to hex string conversion in SASS?". Well… not built-in, but I think this does the trick fairly clearly and with relatively few lines of code:

/** Returns an at least one byte hex value */
@function dec-to-hex($d) {
    $hexVals: "A" "B" "C" "D" "E" "F";
    $base: 16;
    $quotient: $d;
    $result: "";
    @if $d == 0 {
        $result: "00";
    }
    @while $quotient != 0 {
        $mod: $quotient % $base;
        $quotient: floor($quotient / $base);
        @if $mod > 9 {
            $mod: nth($hexVals, $mod - 9);
        }
        @if $d < $base {
            $result: "0" + $mod;
        } @else {
            $result: $mod + $result;
        }
    }
    @return $result;
}

This doesn't prepend a hex qualifier to the string (such as "0x" or "#"), but you could either hard-code that into the last line (@return "#" + $result;), or apply it in-place when you call the function.

like image 180
JPGringo Avatar answered Oct 10 '22 02:10

JPGringo


Another implementation of the last question in your post: "Is there anything that does an integer to hex string conversion in SASS?" this is a shortest version (not working on oldest version, because str-slice may be missing).

@function decToHex($dec) {
    $hex: "0123456789ABCDEF";
    $first: (($dec - $dec % 16)/16)+1;
    $second: ($dec % 16)+1;
    @return str-slice($hex, $first, $first) + str-slice($hex, $second, $second)
}
like image 28
Pierpaolo Cira Avatar answered Oct 10 '22 03:10

Pierpaolo Cira


The previous answers didn't work for us, so here are two quick functions for converting an integer into multiple different bases, including hexadecimal:

@function decimal-to-base($decimal, $to_base, $chars: '0123456789abcdefghijklmnopqrstuvwxyz')
  @if type-of($decimal) != 'number'
    @error '$decimal must be an integer.'
  @if type-of($to_base) != 'number'
    @error '$to-base must be an integer.'
  @if type-of($chars) != 'string'
    @error '$chars must be a string.'
  @if $to_base < 2
    @error '$to-base must be larger than 1.'
  @if $to_base > str-length($chars)
    @error 'Length of $chars must be equal or larger than $to-base.'
  @return _decimal-to-base($decimal, $to_base, $chars)

@function _decimal-to-base($decimal, $to_base, $chars, $_accum: '')
  @if $decimal <= 0
    @return if($_accum != '', $_accum, '0')
  $remainder: $decimal % $to_base
  $char: str-slice($chars, $remainder + 1, $remainder + 1)
  $remaining_decimal: ($decimal - $remainder) / $to_base
  @return _decimal-to-base($remaining_decimal, $to_base, $chars, $char + $_accum)

If you don't care about error handling, you can skip the long first function (which really only validates the arguments and sets the default characters) and just copy the second function.

Also, note that this is written in SASS, not SCSS. For SCSS support, you'll want to sprinkle in some curly brackets and semicolons.

Examples:

  • Decimal to Hexadecimal:
    decimal-to-base(15731618, 16) // "f00ba2".

  • Decimal to binary:
    decimal-to-base(34, 2) // "100010".

  • Timestamp to query string:
    decimal-to-base(1547598870, 2) // "pleb0y".

  • Definitely not Morse code:
    decimal-to-base(34, 2, '-.') // "-...-.".

  • Over-engineered integer to string:
    decimal-to-base(123456, 10) // "123456".

Known caveats: (because this is a dirty implementation)

  • Input decimal must be an integer >= 0.
  • Minimum base is 2.
  • You will want to be careful with large integers.
like image 21
EchoCrow Avatar answered Oct 10 '22 03:10

EchoCrow