defmodule Vnu do @moduledoc "General purpose validation functions for HTML, CSS, and SVG documents." alias Vnu.{Error, Result, Validator} @doc ~S""" Validates the given HTML document. Returns `{:ok, %Vnu.Result{}}` if the validation process finished successfully, and `{:error, %Vnu.Error{}}` otherwise. Note that the `{:ok, %Vnu.Result{}}` return value does not mean necessarily that the document is valid. See `Vnu.valid?/1` and `Vnu.Message` for interpreting the result. ## Options - `:server_url` - The URL of [the Checker server](https://github.com/validator/validator). Defaults to `http://localhost:8888`. - `:filter` - A module implementing the `Vnu.MessageFilter` behavior that will be used to exclude messages matching the filter from the result. Defaults to `nil` (no excluded messages). - `:http_client` - A module implementing the `Vnu.HTTPClient` behaviour that will be used to make the HTTP request to the server. Defaults to `Vnu.HTTPClient.Hackney`. ## Examples iex> Vnu.validate_html(~S( ...> ...> ...>
...> ...> ...> ...> ...> ...>), server_url: System.get_env("VNU_SERVER_URL") || "http://localhost:8888") {:ok, %Vnu.Result{messages: [ %Vnu.Message{ type: :error, message: "Element “head” is missing a required instance of child element “title”.", extract: "=\"utf-8\">\n\n\n\n Vnu.validate_html("", server_url: "http://wrong-domain") {:error, %Vnu.Error{ reason: :unexpected_server_response, message: "Could not contact the server, got error: :nxdomain" }} """ @spec validate_html(String.t(), Keyword.t()) :: {:ok, Result.t()} | {:error, Error.t()} def validate_html(html, opts \\ []) when is_bitstring(html) and is_list(opts) do Validator.validate(html, Keyword.merge(opts, format: :html)) end @doc ~S""" Same as `validate_svg/2` but returns `%Vnu.Result{}` or raises `%Vnu.Error{}`. """ @spec validate_html!(String.t(), Keyword.t()) :: Result.t() | no_return() def validate_html!(html, opts \\ []) when is_bitstring(html) and is_list(opts) do Validator.validate!(html, Keyword.merge(opts, format: :html)) end @doc ~S""" Validates the given CSS document. See `validate_html/2` for the list of options and other details. ## Examples iex> Vnu.validate_css(".button { display: banana; }", server_url: System.get_env("VNU_SERVER_URL") || "http://localhost:8888") {:ok, %Vnu.Result{messages: [ %Vnu.Message{ type: :error, message: "“display”: “banana” is not a “display” value.", extract: ".button { display: banana; }\n", first_line: 1, last_line: 1, first_column: 20, last_column: 25, hilite_length: 6, hilite_start: 19, } ]}} iex> Vnu.validate_css("", server_url: "http://wrong-domain") {:error, %Vnu.Error{ reason: :unexpected_server_response, message: "Could not contact the server, got error: :nxdomain" }} """ @spec validate_css(String.t(), Keyword.t()) :: {:ok, Result.t()} | {:error, Error.t()} def validate_css(css, opts \\ []) when is_bitstring(css) and is_list(opts) do Validator.validate(css, Keyword.merge(opts, format: :css)) end @doc ~S""" Same as `validate_css/2` but returns `%Vnu.Result{}` or raises `%Vnu.Error{}`. """ @spec validate_css!(String.t(), Keyword.t()) :: Result.t() | no_return() def validate_css!(css, opts \\ []) when is_bitstring(css) and is_list(opts) do Validator.validate!(css, Keyword.merge(opts, format: :css)) end @doc ~S""" Validates the given SVG document. See `validate_html/2` for the list of options and other details. ## Examples iex> Vnu.validate_svg(~S( ...> ...> ), server_url: System.get_env("VNU_SERVER_URL") || "http://localhost:8888") {:ok, %Vnu.Result{messages: [ %Vnu.Message{ type: :info, message: "Using the preset for SVG 1.1 + URL + HTML + MathML 3.0 based on the root namespace." }, %Vnu.Message{ type: :error, message: "SVG element “rect” is missing required attribute “width”.", extract: "le\n