diff --git a/fhem/CHANGED b/fhem/CHANGED index 98ee202e2..1291f7ebb 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,6 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it. + - new: lib/FHEM/Text/Unicode: apply text styles in Unicode - feature: 66_EseraMulti: added support for solar sensor Esera 11112 - feature: new module 74_UnifiProtect.pm for Unifi Protect integration (justme1968) diff --git a/fhem/lib/FHEM/Text/Unicode.pm b/fhem/lib/FHEM/Text/Unicode.pm new file mode 100755 index 000000000..e61a843a7 --- /dev/null +++ b/fhem/lib/FHEM/Text/Unicode.pm @@ -0,0 +1,200 @@ +################################################################ +# $Id$ +# Maintainer: Adimarantis +# Library to convert ASCII into formatted Unicode and apply styles like bold or emoticons +# +# This script free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# The GNU General Public License can be found at +# http://www.gnu.org/copyleft/gpl.html. +# A copy is found in the textfile GPL.txt and important notices to the license +# from the author is found in LICENSE.txt distributed with these scripts. +# +# This script is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +################################################################ + +package FHEM::Text::Unicode; +use strict; +use warnings; +use Exporter 'import'; +our @EXPORT_OK = qw (formatTextUnicode formatStringUnicode demoUnicode demoUnicodeHTML); +our %EXPORT_TAGS = (ALL => [@EXPORT_OK]); + +#define globally for demo +#Emoticons +my @mrep = ( + [":\\)","\x{1F600}"], + [":-\\)","\x{1F600}"], + [":\\(","\x{1F641}"], + ["<3","\x{2665}"], + [";-\\)","\x{1F609}"], + [":\\+1:","\x{1F44D}"], + [":smile:","\x{1F600}"], + [":sad:","\x{1F641}"], + [":heart:","\x{2665}"], + [":wink:","\x{1F609}"], + [":thumbsup:","\x{1F44D}"], + ); +#html like styles +my @htags = ( + ["bold" ,"",""], + ["italic","",""], + ["bold-italic","",""], + ["mono","",""], + ["mono","",""], + ["underline","",""], + ["strikethrough","",""], + ["fraktur","",""], + ["script",""], + ["square","",""], +); +#Single replacements in html mode +my @hrep = ( + ["
","\n"], +); +#Markdown styles +my @mtags = ( + ["italic","__","__"], + ["strikethrough","~~","~~"], + ["bold","\\*\\*","\\*\\*"], + ["mono","``","``"], +); + +#Convert text with Markdown/html to Unicode +#Arguments: +#$format: +# html: Only apply HTML-like formatting like .... +# markdown: Only apply Markdown formatting like __text__ and emoticon replacements +# both: Apply both formatting styles +#$msg: ASCII String that should be replaced +#return: Unicode string with applied replacements +#To display all replacements use the demoUnicode() pr demoUnicodeHTML() function +sub formatTextUnicode($$) { + my ($format,$msg) = @_; + my @tags; + my @reps; + + if ($format eq "markdown" || $format eq "both") { + push @tags, @mtags; + push @reps, @mrep; + } + if ($format eq "html" || $format eq "both") { + push @tags, @htags; + push @reps, @hrep; + } + + #First pass, replace singe special characters + foreach my $arr (@reps) { + my @val=@$arr; + $msg =~ s/$val[0]/$val[1]/sg; + } + + my $found=1; + my $matches=0; + my $text; + while ($found && $matches<100) { + $matches++; + $found=0; + foreach my $arr (@tags) { + my @val=@$arr; + $msg =~ /$val[1](.*?)$val[2]/s; + if (defined $1) { + $text=formatStringUnicode($val[0],$1); + if (defined $text) { + $msg =~ s/$val[1].*?$val[2]/$text/s; + $found=1; + } + } + } + } + return $msg; +} + +#Converts normal ASCII into unicode with a special font or style +#$font: Style to be applied: underline, strikethrough, bold, italic, bold-italic, script, fraktur, square, mono +#$str: ASCII String that should be converted +#returns: Unicode String with style applied +sub formatStringUnicode($$) { + my ($font,$str) = @_; + + if ($font eq "underline") { + $str =~ s/./$&\x{332}/g; + return $str; + } + if ($font eq "strikethrough") { + $str =~ s/./$&\x{336}/g; + return $str; + } + + my %uc = ( + "bold" => [0x1d41a,0x1d400,0x1d7ce], + "italic" => [0x1d44e,0x1d434,0x30], + "bold-italic" => [0x1d482,0x1d468,0x30], + "script" => [0x1d4ea,0x1d4d0,0x30], #Using boldface since normal misses some letters + "fraktur" => [0x1d586,0x1d56c,0x30],#Using boldface since normal misses some letters + "square" => [0x1f130,0x1f130,0x30], + "mono" => [0x1d68a,0x1d670,0x30], + ); + + return undef if (! defined $uc{$font}); + + my $rep=chr($uc{$font}[0])."-".chr($uc{$font}[0]+25).chr($uc{$font}[1])."-".chr($uc{$font}[1]+25).chr($uc{$font}[2])."-".chr($uc{$font}[2]+9); + $_=$str; + eval "tr/a-zA-Z0-9/$rep/"; + return undef if $@; +#Special handling for characters missing in some fonts +# 0x1d455 => 0x1d629, #italic h -> italic sans-serif h or 0x210e (planck constant) +# 0x1d4ba => 0x1d452, #script e -> serif e (not used -> using bold script charset which is complete + $_ =~ tr/\x{1d455}\x{1d4ba}/\x{1d629}\x{1d452}/; + return $_; +} + +# Returns a String that is can be embedded in HTML (e.g. FHEM "get") and showcases all possible replacements and their syntax +sub demoUnicodeHTML { + my $str=demoUnicode(); + $str =~ s//sg; + return $str; +} + +# Returns a printable String that showcases all possible replacements and their syntax +sub demoUnicode { + my $str; + $str.="HTML style formatting:\n"; + foreach my $arr (@htags) { + my @val=@$arr; + $str .= formatStringUnicode($val[0],$val[0]." TEXT 123").": $val[1]text$val[2]\n"; + } + $str.="newline:
\n"; + + $str.="\nMarkdown style formatting:\n"; + foreach my $arr (@mtags) { + my @val=@$arr; + my $md= formatStringUnicode($val[0],$val[0]." TEXT 123").": $val[1]text$val[2]\n"; + $md =~ s/\\//g; + $str.=$md; + } + my $i=0; + foreach my $arr (@mrep) { + my @val=@$arr; + my $emo=$val[0]; + $emo =~ s/\\//g; + $str.="$val[1]=$emo "; + $i++; + if ($i>5) { + $str.="\n"; + $i=0; + } + } + return $str; +} + +1; \ No newline at end of file