From 9723d2d41c833a97002ba74a1e3c9c48f9ca5156 Mon Sep 17 00:00:00 2001 From: Evan Czaplicki Date: Sat, 1 Mar 2014 17:26:19 -0500 Subject: [PATCH] Revamp the Text library so that there is an explicit Text.Style record The Style record is needed to allow formatting of text fields! --- libraries/Native/Text.js | 97 ++++++++++++++++++++++++--------------- libraries/Native/Utils.js | 7 --- libraries/Text.elm | 96 ++++++++++++++++++++++---------------- 3 files changed, 116 insertions(+), 84 deletions(-) diff --git a/libraries/Native/Text.js b/libraries/Native/Text.js index 2398586..f777a97 100644 --- a/libraries/Native/Text.js +++ b/libraries/Native/Text.js @@ -4,10 +4,9 @@ Elm.Native.Text.make = function(elm) { elm.Native.Text = elm.Native.Text || {}; if (elm.Native.Text.values) return elm.Native.Text.values; - var JS = Elm.JavaScript.make(elm); - var Utils = Elm.Native.Utils.make(elm); - var Color = Elm.Native.Color.make(elm); var Element = Elm.Graphics.Element.make(elm); + var List = Elm.Native.List.make(elm); + var Utils = Elm.Native.Utils.make(elm); var show = Elm.Native.Show.make(elm).show; function makeSpaces(s) { @@ -51,13 +50,58 @@ Elm.Native.Text.make = function(elm) { return arr.join('
'); } - function toText(str) { return Utils.txt(properEscape(JS.fromString(str))); } + function toText(str) { return Utils.txt(properEscape(str)); } + // conversions from Elm values to CSS + function toTypefaces(list) { + var typefaces = List.toArray(list); + for (var i = typefaces.length; i--; ) { + var typeface = typefaces[i]; + if (typeface.contains(' ')) { + typefaces[i] = "'" + typeface + "'"; + } + } + return typefaces.join(','); + } + function toLine(line) { + var ctor = line.ctor; + var decoration = ctor === 'Under' ? 'underline' : + ctor === 'Over' ? 'overline' : 'line-through'; + return 'text-decoration:' + decoration + ';'; + } + function toColor(c) { + var color = (c._3 === 1) + ? ('rgb(' + c._0 + ', ' + c._1 + ', ' + c._2 + ')') + : ('rgba(' + c._0 + ', ' + c._1 + ', ' + c._2 + ', ' + c._3 + ')'); + return 'color:' + color + ';'; + } + + // setting styles of Text + function style(style, text) { + var newText = '' + return Utils.txt(newText); + } function height(px, text) { return { style: 'font-size:' + px + 'px;', text:text } } - function typeface(name, text) { - return { style: 'font-family:' + name + ';', text:text } + function typeface(names, text) { + return { style: 'font-family:' + toTypefaces(names) + ';', text:text } } function monospace(text) { return { style: 'font-family:monospace;', text:text } @@ -71,14 +115,8 @@ Elm.Native.Text.make = function(elm) { function link(href, text) { return { href: toText(href), text:text }; } - function underline(text) { - return { line: ' underline', text:text }; - } - function overline(text) { - return { line: ' overline', text:text }; - } - function strikeThrough(text) { - return { line: ' line-through', text:text }; + function line(line, text) { + return { style: toLine(line), text:text }; } function color(c, text) { @@ -88,8 +126,8 @@ Elm.Native.Text.make = function(elm) { return { style: 'color:' + color + ';', text:text }; } - function position(align) { - function create(text) { + function block(align) { + return function(text) { var raw = { ctor :'RawHtml', html : Utils.makeText(text), @@ -100,7 +138,6 @@ Elm.Native.Text.make = function(elm) { var pos = A2(Utils.htmlHeight, 0, raw); return A3(Element.newElement, pos._0, pos._1, raw); } - return create; } function markdown(text, guid) { @@ -115,36 +152,22 @@ Elm.Native.Text.make = function(elm) { return A3(Element.newElement, pos._0, pos._1, raw); } - var text = position('left'); - function asText(v) { - return text(monospace(toText(show(v)))); - } - - function plainText(v) { - return text(toText(v)); - } - return elm.Native.Text.values = { toText: toText, height : F2(height), italic : italic, bold : bold, - underline : underline, - overline : overline, - strikeThrough : strikeThrough, + line : F2(line), monospace : monospace, typeface : F2(typeface), color : F2(color), link : F2(link), - justified : position('justify'), - centered : position('center'), - righted : position('right'), - text : text, - plainText : plainText, - markdown : markdown, - - asText : asText, + leftAligned : block('left'), + rightAligned : block('right'), + centered : block('center'), + justified : block('justify'), + markdown : markdown, }; }; diff --git a/libraries/Native/Utils.js b/libraries/Native/Utils.js index e59bab0..51ac6ef 100644 --- a/libraries/Native/Utils.js +++ b/libraries/Native/Utils.js @@ -76,14 +76,8 @@ Elm.Native.Utils.make = function(elm) { function makeText(text) { var style = ''; - var line = ''; var href = ''; while (true) { - if (text.line) { - line += text.line; - text = text.text; - continue; - } if (text.style) { style += text.style; text = text.text; @@ -95,7 +89,6 @@ Elm.Native.Utils.make = function(elm) { continue; } if (href) text = '' + text + ''; - if (line) style += 'text-decoration:' + line + ';'; if (style) text = '' + text + ''; return text; } diff --git a/libraries/Text.elm b/libraries/Text.elm index 37d180a..1799cb7 100644 --- a/libraries/Text.elm +++ b/libraries/Text.elm @@ -6,13 +6,21 @@ module Text where @docs toText # Creating Elements -@docs plainText, asText, text, centered, justified, righted +@docs leftAligned, rightAligned, centered, justified -# Formatting -@docs color, typeface, height, link +# Style and Links +@docs Style, style, Line, link -# Simple Formatting -@docs monospace, bold, italic, underline, overline, strikeThrough +# Convenience Functions + +There are two convenience functions for creating an `Element` which can be +useful when debugging or prototyping: + +@docs plainText, asText + +There are also a bunch of functions to set parts of a `Style` individually: + +@docs typeface, monospace, height, color, bold, italic, line -} @@ -25,75 +33,82 @@ import Native.Text data Text = Text +data Line = Under | Over | Through + +{-| Representation of all the ways you can style `Text`. +-} +type Style = + { typeface : [String] + , height : Maybe Float + , color : Color + , bold : Bool + , italic : Bool + , line : Maybe Line + } + {-| Convert a string into text which can be styled and displayed. -} toText : String -> Text toText = Native.Text.toText -{-| Set the typeface of some text. The first argument should be a comma -separated listing of the desired typefaces: - - "helvetica, arial, sans-serif" - -Works the same as the CSS font-family property. +{-| Set the style of some text. -} -typeface : String -> Text -> Text +style : Style -> Text -> Text +style = Native.Text.style + +{-| Provide a list of prefered typefaces for some text. + + ["helvetica","arial","sans-serif"] + +Not everyone has access to the same typefaces, so rendering will use the first +typeface in the list that is found on the user's computer. If there are no +matches, it will use their default typeface. Works the same as the CSS +font-family property. +-} +typeface : [String] -> Text -> Text typeface = Native.Text.typeface {-| Switch to a monospace typeface. Good for code snippets. -} monospace : Text -> Text monospace = Native.Text.monospace -{-| Create a link. -} +{-| Create a link. + + link "http://elm-lang.org" (toText "Elm Website") +-} link : String -> Text -> Text link = Native.Text.link -{-| Set the height of text in pixels. -} height : Float -> Text -> Text height = Native.Text.height -{-| Set the color of a string. -} color : Color -> Text -> Text color = Native.Text.color -{-| Make a string bold. -} bold : Text -> Text bold = Native.Text.bold -{-| Italicize a string. -} italic : Text -> Text italic = Native.Text.italic -{-| Draw a line above a string. -} -overline : Text -> Text -overline = Native.Text.overline +line : Line -> Text -> Text +line = Native.Text.line -{-| Underline a string. -} -underline : Text -> Text -underline = Native.Text.underline +leftAligned : Text -> Element +leftAligned = Native.Text.leftAligned -{-| Draw a line through a string. -} -strikeThrough : Text -> Text -strikeThrough = Native.Text.strikeThrough +rightAligned : Text -> Element +rightAligned = Native.Text.rightAligned -{-| Display justified, styled text. -} -justified : Text -> Element -justified = Native.Text.justified - -{-| Display centered, styled text. -} centered : Text -> Element centered = Native.Text.centered -{-| Display right justified, styled text. -} -righted : Text -> Element -righted = Native.Text.righted - -{-| Display styled text. -} -text : Text -> Element -text = Native.Text.text +justified : Text -> Element +justified = Native.Text.justified {-| Display a plain string. -} plainText : String -> Element -plainText = Native.Text.plainText +plainText str = + leftAligned (toText str) {-| for internal use only -} markdown : Element @@ -107,4 +122,5 @@ the browser: Excellent for debugging. -} asText : a -> Element -asText = Native.Text.asText +asText value = + leftAligned (monospace (toText (show value)))