defmodule Gulib.String.UbbFormat do @moduledoc """ discuzz论坛的ubb格式的正文的转换 """ @tags %{ "Audio (Unsized)" => [ ~r/\[audio\]\s+(.*?)\s+\[\/audio\]/mi, "", "Display an audio", "[audio]http://www.google.com/intl/en_ALL/images/logo.gif[/audio]", "audio", ], "Audio (Unsized) No Spaces" => [ ~r/\[audio\](.*?)\[\/audio\]/mi, "", "Display an audio", "[audio]http://www.google.com/intl/en_ALL/images/logo.gif[/audio]", "audio", ], "Media (Sized)" => [ ~r/\[media=(.*?)\](.*?)\[\/media\]/mi, "\\2", "Media", "[media=250,360]http://www.google.com/intl/en_ALL/images/logo.gif[/media]", "media", ], "Media (X Sized)" => [ ~r/\[media=x,(.*?)\](.*?)\[\/media\]/mi, "\\2", "Media", "[media=x,250,360]http://www.google.com/intl/en_ALL/images/logo.gif[/media]", "media", ], "Media (SWF Sized)" => [ ~r/\[media=swf,(\d{1,4})[x|\,](\d{1,4})\]\s*([^\[\<\r\n]+?)\s*\[\/flash\]/mi, "", "Display an flash with a set width and height", "[flash=250,360]http://www.google.com/intl/en_ALL/images/logo.gif[/flash]", "flash", ], "Font" => [ ~r/\[font=(.*?)\](.*?)\[\/font\]/mi, "\\2", "Font family", "", "font", ], "Free" => [ ~r/\[free(:.*)?\](.*?)\[\/free\1?\]/mi, "
\\2
", "Free text", "Look [free]here[/free]", "free", ], "Indent" => [ ~r/\[indent(:.*)?\](.*?)\[\/indent\1?\]/mi, "\\2", "Embolden text", "Look [indent]here[/indent]", "indent", ], "Bold" => [ ~r/\[b(:.*)?\](.*?)\[\/b\1?\]/mi, "\\2", "Embolden text", "Look [b]here[/b]", "bold", ], "Hide (Other)" => [ ~r/\[hide(=.+)?\](.*?)\[\/hide\1?\]/mi, "

\\2

", "hidden text", "Even my [hide]cat[/hide] was chasing the mailman!", "italics", ], "Italics (Other)" => [ ~r/\[i(=.+)?\](.*?)\[\/i\1?\]/mi, "\\2", "Italicize or emphasize text", "Even my [i]cat[/i] was chasing the mailman!", "italics", ], "Italics" => [ ~r/\[i(:.+)?\](.*?)\[\/i\1?\]/mi, "\\2", "Italicize or emphasize text", "Even my [i]cat[/i] was chasing the mailman!", "italics", ], "Underline" => [ ~r/\[u(:.+)?\](.*?)\[\/u\1?\]/mi, "\\2", "Underline", "Use it for [u]important[/u] things or something", "underline", ], "Strikeout" => [ ~r/\[s(:.+)?\](.*?)\[\/s\1?\]/mi, "\\2", "Strikeout", "[s]nevermind[/s]", "strikeout", ], "Delete" => [ ~r/\[del(:.+)?\](.*?)\[\/del\1?\]/mi, "\\2", "Deleted text", "[del]deleted text[/del]", "delete", ], "Insert" => [ ~r/\[ins(:.+)?\](.*?)\[\/ins\1?\]/mi, "\\2", "Inserted Text", "[ins]inserted text[/del]", "insert", ], "Code" => [ ~r/\[code(:.+)?\](.*?)\[\/code\1?\]/mi, "\\2", "Code Text", "[code]some code[/code]", "code", ], "Size" => [ ~r/\[size=("|'|)(.*?)\1\](.*?)\[\/size\]/mi, "\\3", "Change text size", "[size=20]Here is some larger text[/size]", "size", ], "Color" => [ ~r/\[color=("|'|)(\w+|\#\w{6})\1(:.+)?\](.*?)\[\/color\3?\]/mi, "\\4", "Change text color", "[color=red]This is red text[/color]", "color", ], "Ordered List" => [ ~r/\[ol\](.*?)\[\/ol\]/mi, "
    \\1
", "Ordered list", "My favorite people (alphabetical order): [ol][li]Jenny[/li][li]Alex[/li][li]Beth[/li][/ol]", "orderedlist", ], "Unordered List" => [ ~r/\[ul\](.*?)\[\/ul\]/mi, "", "Unordered list", "My favorite people (order of importance): [ul][li]Jenny[/li][li]Alex[/li][li]Beth[/li][/ul]", "unorderedlist", ], "List Item" => [ ~r/\[li\](.*?)\[\/li\]/mi, "
  • \\1
  • ", "List item", "See ol or ul", "listitem", ], "List Item (alternative)" => [ ~r/\[\*(:[^\[]+)?\]([^(\[|\<)]+)/mi, "
  • \\2
  • ", "List item (alternative)", "[*]list item", "listitem", ], "Unordered list (alternative)" => [ ~r/\[list(:.*)?\]((?:(?!\[list(:.*)?\]).)*)\[\/list(:.)?\1?\]/mi, "", "Unordered list item", "[list][*]item 1[*] item2[/list]", "list", ], "Ordered list (numerical)" => [ ~r/\[list=1(:.*)?\](.+)\[\/list(:.)?\1?\]/mi, "
      \\2
    ", "Ordered list numerically", "[list=1][*]item 1[*] item2[/list]", "list", ], "Ordered list (alphabetical)" => [ ~r/\[list=a(:.*)?\](.+)\[\/list(:.)?\1?\]/mi, "
      \\2
    ", "Ordered list alphabetically", "[list=a][*]item 1[*] item2[/list]", "list", ], "Definition List" => [ ~r/\[dl\](.*?)\[\/dl\]/mi, "
    \\1
    ", "List of terms/items and their definitions", "[dl][dt]Fusion Reactor[/dt][dd]Chamber that provides power to your... nerd stuff[/dd][dt]Mass Cannon[/dt][dd]A gun of some sort[/dd][/dl]", "definelist", ], "Definition Term" => [ ~r/\[dt\](.*?)\[\/dt\]/mi, "
    \\1
    ", "List of definition terms", "[dt]definition term[/dt]", "defineterm", ], "Definition Definition" => [ ~r/\[dd\](.*?)\[\/dd\]/mi, "
    \\1
    ", "Definition definitions", "[dd]my definition[/dd/", "definition", ], "Quote" => [ ~r/\[quote(:.*)?=(?:")?(.*?)(?:")?\](.*?)\[\/quote\1?\]/mi, "
    \\2
    \\3
    ", "Quote with citation", "[quote=mike]Now is the time...[/quote]", "quote", ], "Quote (Sourceless)" => [ ~r/\[quote(:.*)?\](.*?)\[\/quote\1?\]/mi, "
    \\2
    ", "Quote (sourceclass)", "[quote]Now is the time...[/quote]", "quote", ], "Link" => [ ~r/\[url=(?:")?(.*?)(?:")?\](.*?)\[\/url\]/mi, "\\2", "Hyperlink to somewhere else", "Maybe try looking on [url=http://google.com]Google[/url]?", "link", ], "Link (Implied)" => [ ~r/\[url\](.*?)\[\/url\]/mi, "\\1", "Hyperlink (implied)", "Maybe try looking on [url]http://google.com[/url]", "link", ], "Link (Automatic)" => [ ~r/(\A|\s)(https?:\/\/[^\s<]+)/, " \\2", "Hyperlink (automatic)", "Maybe try looking on http://www.google.com", "link", ], "Link (Automatic without leading http(s))" => [ ~r/(\A|\s)(www\.[^\s<]+)/, " \\2", "Hyperlink (automatic without leading http(s))", "Maybe try looking on www.google.com", "link", ], "Flash (Unsized)" => [ ~r/\[flash\](.*?)\[\/flash\]/mi, "", "Display an flash with a set width and height", "[flash]http://www.google.com/intl/en_ALL/images/logo.gif[/flash]", "flash", ], "Flash (Sized)" => [ ~r/\[flash=(\d{1,4})[x|\,](\d{1,4})\]\s*([^\[\<\r\n]+?)\s*\[\/flash\]/mi, "", "Display an flash with a set width and height", "[flash=250,360]http://www.google.com/intl/en_ALL/images/logo.gif[/flash]", "flash", ], "Image (Sized)" => [ ~r/\[img=(\d{1,4})[x|\,](\d{1,4})\]\s*([^\[\<\r\n]+?)\s*\[\/img\]/mi, "", "Display an image with a set width and height", "[img=250,360]http://www.google.com/intl/en_ALL/images/logo.gif[/img]", "image", ], "Image (Resized)" => [ ~r/\[img(:.+)? size=("|'|)(\d+)x(\d+)\2\](.*?)\[\/img\1?\]/mi, "", "Display an image with a set width and height", "[img size=96x96]http://www.google.com/intl/en_ALL/images/logo.gif[/img]", "image", ], "Image (Alternative)" => [ ~r/\[img=([^\[\]].*?)\]/mi, "\"\"", "Display an image (alternative format)", "[img=http://myimage.com/logo.gif]", "image", ], "Image (Aligned)" => [ ~r/\[img(:.+)? align=(left|right)\](.*?)\[\/img\1?\]/mi, "\"\"", "Display an aligned image", "[img align=right]http://catsweekly.com/crazycat.jpg[/img]", "image", ], "Image" => [ ~r/\[img(:.+)?\]([^\[\]].*?)\[\/img\1?\]/mi, "\"\"", "Display an image", "Check out this crazy cat: [img]http://catsweekly.com/crazycat.jpg[/img]", "image", ], "YouTube" => [ ~r/\[youtube\](.*?)\?v=([\w\d\-]+).*?\[\/youtube\]/mi, "", "Display a video from YouTube.com", "[youtube]http://youtube.com/watch?v=E4Fbk52Mk1w[/youtube]", "video", ], "YouTube (Alternative)" => [ ~r/\[youtube\](.*?)\/v\/([\w\d\-]+)\[\/youtube\]/mi, "", "Display a video from YouTube.com (alternative format)", "[youtube]http://youtube.com/watch/v/E4Fbk52Mk1w[/youtube]", "video", ], "Vimeo" => [ ~r/\[vimeo\](.*?)\/(\d+)\[\/vimeo\]/mi, "", "Display a video from Vimeo", "[vimeo]http://www.vimeo.com/3485239[/vimeo]", "video", ], "Google Video" => [ ~r/\[gvideo\](.*?)\?docid=([-]{0,1}\d+).*\[\/gvideo\]/mi, " ", "Display a video from Google Video", "[gvideo]http://video.google.com/videoplay?docid=-2200109535941088987[/gvideo]", "video", ], "Email" => [ ~r/\[email[^:=]?\](((?!\[\/email\]).)*)\[\/email\]/mi, "\\1", "Link to email address", "[email]wadus@wadus.com[/email]", "email", ], "Email (alternative)" => [ ~r/\[email[:=]([^\]]+)\](((?!\[\/email\]).)*)(\[\/email\1?\])?/mi, "\\2", "Link to email address", "[email:wadus@wadus.com]Email Me[/email]", "email", ], "Align" => [ ~r/\[align=(.*?)\](.*?)\[\/align\]/mi, "\\2", "Align this object using float", "Here's a wrapped image: [align=right][img]image.png[/img][/align]", "align", ], "Left" => [ ~r/\[left(:.+)?\](.*?)\[\/left\1?\]/mi, "
    \\2
    ", "Aligns contents along the left side", "[left]Left-aligned content[/left]", "left", ], "Center" => [ ~r/\[center(:.+)?\](.*?)\[\/center\1?\]/mi, "
    \\2
    ", "Aligns contents on the center", "[center]Centered content[/center]", "center", ], "Right" => [ ~r/\[right(:.+)?\](.*?)\[\/right\1?\]/mi, "
    \\2
    ", "Aligns contents along the right side", "[right]Right-aligned content[/right]", "right", ], "Hr Break" => [ ~r/\[hr\]/mi, "
    ", "Inserts line break tag", "One[hr]Two[hr]Three lines!", "hr", ], "Line break" => [ ~r/\[br\]/mi, "
    ", "Inserts line break tag", "One[br]Two[br]Three lines!", "br", ] } @doc """ 转换过成HTML ## opts * escape_html: true """ def to_html(text, opts \\ []) do escape_html = Keyword.get(opts, :escape_html, true) text = if escape_html do text |> Gulib.String.HTML.escape else text end text = text |> String.replace(~r/\[p=(.*?)\]/mi, "

    ") |> String.replace(~r/\n+/, "\n") |> String.replace("[p]", "

    ") |> String.replace("[/p]", "

    ") |> String.replace(~r/\[color=(.*?)\]/mi, "") |> String.replace("[/color]", "") |> String.replace(~r/\[backcolor=(.*?)\]/mi, "") |> String.replace("[/backcolor]", "") |> String.replace(~r/\[table=(.*?)\]/mi, "") |> String.replace("[table]", "
    ") |> String.replace("[/table]", "
    ") |> String.replace(~r/\[tr=(.*?)\]/mi, "") |> String.replace("[tr]", "") |> String.replace("[/tr]", "") |> String.replace(~r/\[td=(\d{1,4})[x|\,](\d{1,4})[x|\,](\d{1,4})\]/mi, "") |> String.replace(~r/\[td=(\d{1,4})[x|\,](\d{1,4})\]/mi, "") |> String.replace(~r/\[td=(\d{1,4})\]/mi, "") |> String.replace(~r/\[td=(.*?)\]/mi, "") |> String.replace("[td]", "") |> String.replace("[/td]", "") text = @tags |> Map.values |> Enum.reduce(text, fn(rule, acc) -> pattern = rule |> Enum.at(0) replacement = rule |> Enum.at(1) acc |> String.replace(pattern, replacement) end) text end end