Round out basic html
This commit is contained in:
parent
33a4ad6dc8
commit
8098ed3c53
2 changed files with 45 additions and 21 deletions
|
@ -3,17 +3,20 @@ module SSG.HTML
|
||||||
import public SSG.HTML.ElementTypes
|
import public SSG.HTML.ElementTypes
|
||||||
|
|
||||||
import Data.String
|
import Data.String
|
||||||
|
import Decidable.Equality
|
||||||
|
|
||||||
import Structures.Dependent.DList
|
import Structures.Dependent.DList
|
||||||
|
|
||||||
export infix 8 =$
|
export infix 8 =$
|
||||||
|
|
||||||
|
||| An attribute within an HTML tag
|
||||||
public export
|
public export
|
||||||
data Attribute : Type where
|
data Attribute : Type where
|
||||||
-- TODO: Add some structure here, maybe make `=$` a smart constructor
|
-- TODO: Add some structure here, maybe make `=$` a smart constructor
|
||||||
(=$) : (attribute, value : String) -> Attribute
|
(=$) : (attribute, value : String) -> Attribute
|
||||||
|
|
||||||
namespace Attribute
|
namespace Attribute
|
||||||
|
||| Convert an attribute tag into a string suitable for rendering a tag with
|
||||||
export
|
export
|
||||||
toString : Attribute -> String
|
toString : Attribute -> String
|
||||||
toString (attribute =$ value) =
|
toString (attribute =$ value) =
|
||||||
|
@ -24,48 +27,68 @@ namespace Attribute
|
||||||
then "'\{value}'"
|
then "'\{value}'"
|
||||||
else value
|
else value
|
||||||
|
|
||||||
|
||| An element in an HTML document, indexed by the tag type.
|
||||||
|
|||
|
||||||
|
||| Raw text has a tag type of `""`
|
||||||
public export
|
public export
|
||||||
data Tag : String -> Type where
|
data Html : String -> Type where
|
||||||
-- TODO: Find a way to move this out of tag
|
||| Textual content outside of a tag
|
||||||
||| Raw text, represented as a tag for compatibility
|
Text : (content : String)
|
||||||
Raw : (content : String)
|
-> Html ""
|
||||||
-> Tag ""
|
|
||||||
||| A void type tag, has attributes, no contents
|
||| A void type tag, has attributes, no contents
|
||||||
Void : (type : String) -> {auto void_prf : IsVoid type}
|
Void : (type : String) -> {auto void_prf : IsVoid type}
|
||||||
-> (attributes : List Attribute)
|
-> (attributes : List Attribute)
|
||||||
-> Tag type
|
-> Html type
|
||||||
||| A normal type tag, has attributes, and contents
|
||| A normal type tag, has attributes, and contents
|
||||||
Normal : (type : String) -> {auto normal_prf : IsNormal type}
|
Normal : (type : String) -> {auto normal_prf : IsNormal type}
|
||||||
-> (attributes : List Attribute)
|
-> (attributes : List Attribute)
|
||||||
-- TODO: Erase content_types
|
-> {content_types : _} -> (contents : DList _ Html content_types)
|
||||||
-> {content_types : _} -> (contents : DList _ Tag content_types)
|
-> Html type
|
||||||
-> Tag type
|
|
||||||
||| A raw text or an escapable raw text element
|
||| A raw text or an escapable raw text element
|
||||||
RawText : (type : String)
|
RawText : (type : String)
|
||||||
-> {auto raw_prf : Either (IsRawText type) (IsEscapableRawText type)}
|
-> {auto raw_prf : Either (IsRawText type) (IsEscapableRawText type)}
|
||||||
-> (attributes : List Attribute)
|
-> (attributes : List Attribute)
|
||||||
-> (content : String)
|
-> (content : String)
|
||||||
-> Tag type
|
-> Html type
|
||||||
|
|
||||||
namespace Tag
|
namespace Html
|
||||||
viewIndented : (indent_level : Nat) -> Tag type -> String
|
||| Convert to a "pretty printed" string containing the html, starting at the
|
||||||
viewIndented indent_level (Raw content) =
|
||| specified indentation level
|
||||||
|
viewIndented : (indent_level : Nat) -> Html type -> String
|
||||||
|
viewIndented indent_level (Text content) =
|
||||||
replicate (indent_level * 2) ' ' ++ content
|
replicate (indent_level * 2) ' ' ++ content
|
||||||
viewIndented indent_level (Void type attributes) =
|
viewIndented indent_level (Void type attributes) =
|
||||||
let indent = replicate (indent_level * 2) ' '
|
let indent = replicate (indent_level * 2) ' ' in
|
||||||
in if length attributes > 0
|
if length attributes > 0
|
||||||
then
|
then
|
||||||
let attrs = joinBy " " $ map toString attributes
|
let attrs = joinBy " " $ map toString attributes
|
||||||
in "<\{type} \{attrs} />"
|
in "<\{type} \{attrs} />"
|
||||||
else "<\{type} />"
|
else "<\{type} />"
|
||||||
viewIndented indent_level (Normal type attributes contents) =
|
viewIndented indent_level (Normal type attributes {content_types} contents) =
|
||||||
?viewIndented_rhs_2
|
let indent = replicate (indent_level * 2) ' ' in
|
||||||
|
-- Special handling if the tag contains exactly one `Text` element, we won't
|
||||||
|
-- do any newlines between the tag and its contents in that case
|
||||||
|
case decEq content_types [""] of
|
||||||
|
Yes prf => ?viewIndented_rhs_4
|
||||||
|
No contra =>
|
||||||
|
let start = "\{indent}<\{type}>\n"
|
||||||
|
end = "\{indent}</\{type}>\n"
|
||||||
|
inner = joinBy "\n" $
|
||||||
|
dMap (\_, x => viewIndented (S indent_level) x) contents
|
||||||
|
in start ++ end ++ inner
|
||||||
viewIndented indent_level (RawText type attributes content) =
|
viewIndented indent_level (RawText type attributes content) =
|
||||||
?viewIndented_rhs_3
|
let indent = replicate (indent_level * 2) ' ' in
|
||||||
|
if length attributes > 0
|
||||||
|
then
|
||||||
|
let attrs = joinBy " " $ map toString attributes
|
||||||
|
in "<\{type} \{attrs}>\{content}</\{type}>"
|
||||||
|
else "<\{type}>\{content}</\{type}>"
|
||||||
|
|
||||||
view : Tag type -> String
|
||| Convert to a "pretty printed" string containing the html
|
||||||
|
view : Html type -> String
|
||||||
view = viewIndented 0
|
view = viewIndented 0
|
||||||
|
|
||||||
render : Tag "html" -> String
|
||| Render a top level html document, including the doctype tag
|
||||||
|
render : Html "html" -> String
|
||||||
render x =
|
render x =
|
||||||
"<!DOCTYPE HTML>\n" ++ viewIndented 0 x
|
"<!DOCTYPE HTML>\n" ++ viewIndented 0 x
|
||||||
|
|
3
todo.org
3
todo.org
|
@ -2,4 +2,5 @@
|
||||||
** TODO Special handling for =pre= in =view=
|
** TODO Special handling for =pre= in =view=
|
||||||
** TODO Smart spec compliance for =attribute=
|
** TODO Smart spec compliance for =attribute=
|
||||||
Probably want to refine the attribute and value strings, and be smarter about how we choose to quote the value string.
|
Probably want to refine the attribute and value strings, and be smarter about how we choose to quote the value string.
|
||||||
** TODO Move =Raw= out of =Tag=
|
** NO Move =Raw= out of =Tag=
|
||||||
|
Decided to rename =Tag= to =Html=, and =Raw= to =Text=, which makes this make sense
|
||||||
|
|
Loading…
Add table
Reference in a new issue