From 43c641a25c401cbb60c02afb807329b286859245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 10 Mar 2019 17:04:07 +0100 Subject: [PATCH] Implement `Html.Parser.nodeToString`. Fixes #7. --- CHANGELOG.md | 7 ++++- elm.json | 2 +- src/Html/Parser.elm | 64 ++++++++++++++++++++++++++++++++++++++++++--- tests/Main.elm | 36 +++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 261611e..245b39d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +## [2.3.0] - 2019-03-10 +### Added +- `Html.Parser.nodeToString` to turn parser nodes back into its HTML representation. + ## [2.2.0] - 2019-02-27 ### Added - Expose `Html.Parser.node` to allow other folks to build different parsers on top of this one! @@ -38,7 +42,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. [named-character-references]: https://www.w3.org/TR/html5/syntax.html#named-character-references -[Unreleased]: https://github.com/hecrj/html-parser/compare/2.2.0...HEAD +[Unreleased]: https://github.com/hecrj/html-parser/compare/2.3.0...HEAD +[2.3.0]: https://github.com/hecrj/html-parser/compare/2.2.0...2.3.0 [2.2.0]: https://github.com/hecrj/html-parser/compare/2.1.0...2.2.0 [2.1.0]: https://github.com/hecrj/html-parser/compare/2.0.1...2.1.0 [2.0.1]: https://github.com/hecrj/html-parser/compare/2.0.0...2.0.1 diff --git a/elm.json b/elm.json index db5846e..ee3fd5f 100644 --- a/elm.json +++ b/elm.json @@ -3,7 +3,7 @@ "name": "hecrj/html-parser", "summary": "Parse HTML 5 in Elm", "license": "BSD-3-Clause", - "version": "2.2.0", + "version": "2.3.0", "exposed-modules": [ "Html.Parser", "Html.Parser.Util" diff --git a/src/Html/Parser.elm b/src/Html/Parser.elm index 48f51d6..5da6538 100644 --- a/src/Html/Parser.elm +++ b/src/Html/Parser.elm @@ -1,6 +1,6 @@ module Html.Parser exposing ( run, Node(..), Attribute - , node + , node, nodeToString ) {-| Parse HTML 5 in Elm. @@ -9,14 +9,14 @@ See @docs run, Node, Attribute -# Parser internals +# Internals If you are building a parser of your own using [`elm/parser`][elm-parser] and you need to parse HTML... This section is for you! [elm-parser]: https://package.elm-lang.org/packages/elm/parser/latest -@docs node +@docs node, nodeToString -} @@ -67,7 +67,7 @@ type alias Attribute = ( String, String ) -{-| Parses an HTML node. +{-| Parse an HTML node. You can use this in your own parser to add support for HTML 5. @@ -81,6 +81,62 @@ node = ] +{-| Turn a parser node back into its HTML string. + +For instance: + + Element "a" + [ ( "href", "https://elm-lang.org" ) ] + [ Text "Elm" ] + |> toString + +Produces `Elm`. + +-} +nodeToString : Node -> String +nodeToString node_ = + let + attributeToString ( attr, value ) = + attr ++ "=\"" ++ value ++ "\"" + in + case node_ of + Text text_ -> + text_ + + Element name attributes children -> + let + maybeAttributes = + case attributes of + [] -> + "" + + _ -> + " " ++ String.join "" (List.map attributeToString attributes) + in + if isVoidElement name then + String.concat + [ "<" + , name + , maybeAttributes + , ">" + ] + + else + String.concat + [ "<" + , name + , maybeAttributes + , ">" + , String.join "" (List.map nodeToString children) + , "" + ] + + Comment comment_ -> + "" + + -- Text diff --git a/tests/Main.elm b/tests/Main.elm index 703c9d6..8258d36 100644 --- a/tests/Main.elm +++ b/tests/Main.elm @@ -91,6 +91,41 @@ nodeTests = ] +nodeToStringTests : Test +nodeToStringTests = + describe "nodeToString" + [ test "simple link" <| + \_ -> + Element "a" [ ( "href", "https://elm-lang.org" ) ] [ Text "Elm" ] + |> Html.Parser.nodeToString + |> Expect.equal "Elm" + , test "container" <| + \_ -> + Element "div" + [] + [ Element "p" [] [ Text "Hello," ] + , Element "p" [] [ Text "World!" ] + ] + |> Html.Parser.nodeToString + |> Expect.equal "

Hello,

World!

" + , test "void element" <| + \_ -> + Element "br" [] [ Element "a" [] [ Text "should be ignored" ] ] + |> Html.Parser.nodeToString + |> Expect.equal "
" + , test "comment" <| + \_ -> + Comment "This is a comment" + |> Html.Parser.nodeToString + |> Expect.equal "" + , test "text" <| + \_ -> + Text "Hello, world!" + |> Html.Parser.nodeToString + |> Expect.equal "Hello, world!" + ] + + scriptTests : Test scriptTests = describe "Script" @@ -148,6 +183,7 @@ suite = describe "HtmlParser" [ textNodeTests , nodeTests + , nodeToStringTests , commentTests , attributeTests , errorTests