defmodule MusicLibraryWeb.ArtistLive.Biography do @moduledoc """ Helper functions for building and rendering artist biographies from Wikipedia and Last.fm data. """ alias MusicLibrary.Artists.ArtistInfo alias MusicLibraryWeb.Markdown alias Phoenix.HTML @spec build(ArtistInfo.t()) :: map() | nil def build(artist_info) do bio_html = ArtistInfo.wikipedia_bio(artist_info) if bio_html do %{ source: "Wikipedia", summary_html: ArtistInfo.wikipedia_summary(artist_info), bio_html: bio_html, url: ArtistInfo.wikipedia_url(artist_info), description: ArtistInfo.wikipedia_description(artist_info) } end end # Bios start with text, then a link to read more on Last.fm, followed by a license text. # We split the bio at the read more link in order to render the license separately. @spec render_bio(String.t()) :: Phoenix.HTML.safe() def render_bio(bio) do last_fm_link_regex = ~r/\.*\s*/ case String.split(bio, last_fm_link_regex, include_captures: true) do [text, link, ""] -> reformatted_bio = Enum.join([ text, ~s(

#{link}

) ]) render_content(reformatted_bio) [text, link, license] -> reformatted_bio = Enum.join([ text, ~s(

#{link}

), ~s(

#{license}

) ]) render_content(reformatted_bio) other -> render_content(Enum.join(other)) end end @spec remove_read_more_link(String.t()) :: Phoenix.HTML.safe() def remove_read_more_link(summary) do last_fm_link_regex = ~r/\.*\s*/ reformatted_summary = String.replace(summary, last_fm_link_regex, "") render_content(reformatted_summary) end # sobelow_skip ["XSS.Raw"] # Markdown.to_html/1 sanitizes HTML via MDEx (ammonia) defp render_content(content) do content |> Markdown.to_html() |> HTML.raw() end end