Skip to content

Instantly share code, notes, and snippets.

@robotdana
Created June 27, 2014 13:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robotdana/2e87076accbb55e36288 to your computer and use it in GitHub Desktop.
Save robotdana/2e87076accbb55e36288 to your computer and use it in GitHub Desktop.
Hanging Punctuation
$.fn.hangQuotes = (fname) ->
quote = /(?:(^|\s)([`'"“”‘’«»‹›]+)|([`'"“”‘’«»‹›]+)($|\s))/g
replacement = '$1<span class="hq">$2$3</span>$4'
className = 'hq'
exclude = 'code,table'
el = this
wrapQuotes = ->
$(el).textNodes().each ->
unless $(this).parent().hasClass(className) || $(this).closest(exclude)[0]?
$(this).replaceWith($(this).text().replace(quote, replacement))
positionQuotes = ->
$(el).find(".#{className}").css(position:'',left:'',right:'').each ->
parent = $(this).parent().relativise()
edge = $(this).leadingEdge()
parentPadding = $.rawLength parent.css("padding-#{edge}")
textWidth = $(this).width()
if textWidth && $(this).position()[edge] == parentPadding
$(this).css(position:'absolute')
if $(this).position()[edge] == parentPadding
outdent = textWidth - parentPadding
$(this).css(edge, $.em(-outdent, this))
else
$(this).css(position:'')
return do (fname) ->
if fname != 'reposition'
wrapQuotes()
if fname != 'wrap'
positionQuotes()
$(el)
$.rawLength = (numberWithUnit, emMultiplier=16) ->
number = parseFloat numberWithUnit, 10
if !numberWithUnit?
0
else if String(number) == String(numberWithUnit)
number
else if numberWithUnit.match /px$/
number
else if numberWithUnit.match /vw$/
($(window).width() / 100) * number
else if numberWithUnit.match /vh$/
($(window).height() / 100) * number
else if numberWithUnit.match /em$/
unless $.isNumeric(emMultiplier)
emMultiplier = $.rawLength $(emMultiplier).css('fontSize')
emMultiplier * number
else
number
$.fn.relativise = ->
$(this).each ->
if $(this).css('position') == 'static'
$(this).css('position', 'relative')
$(this).data('added-position', true)
$.fn.textNodes = ->
textNodes = $(this).contents().filter -> (this? && this.nodeType == 3)
if $(this).children()[0]?
$(this).children().textNodes().add(textNodes)
else
textNodes
$.fn.leadingEdge = ->
textAlign = $(this).css('textAlign')
textDirection = $(this).css('direction')
if textAlign == 'left' ||
textAlign == 'start' && textDirection == 'ltr' ||
textAlign == 'end' && textDirection == 'rtl'
'left'
else
'right'
$.em = (number, context) ->
fontSize = $.rawLength $(context).css('fontSize')
(number / fontSize) + 'em'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment