How to add color to symbol objects? - powershell

I am looking to provide users with a size list that also compares against a threshold. if threshold is exceeded, that should generate a RED X mark. otherwise, if threshold is not exceeded that should generate a green checkmark
i found this code:
$greenCheck = #{
Object = [Char]8730
ForegroundColor = 'Green'
NoNewLine = $true
}
Write-Host #greenCheck
that is fantastic but requires write-host...i cant just call it like this in other words #greenCheck
The splatting operator '#' cannot be used to reference variables in
an expression. '#greenCheck' can be used only as an argument to a
command. To reference variables in an expression use '$greenCheck'.
i found this other code here
$symbols = [PSCustomObject] #{
SMILEY_WHITE = ([char]9786)
SMILEY_BLACK = ([char]9787)
GEAR = ([char]9788)
HEART = ([char]9829)
DIAMOND = ([char]9830)
CLUB = ([char]9827)
SPADE = ([char]9824)
CIRCLE = ([char]8226)
NOTE1 = ([char]9834)
NOTE2 = ([char]9835)
MALE = ([char]9794)
FEMALE = ([char]9792)
YEN = ([char]165)
COPYRIGHT = ([char]169)
PI = ([char]960)
TRADEMARK = ([char]8482)
CHECKMARK = ([char]8730)
}
this one is perfect! but it doesnt have colors. how can i add colors to the object?
also, is there more symbols i can find like an X mark? or i would have to just use good ol' 'X' char?

For a green checkmark and a red x try: "$([char]0x1b)[92m$([char]8730) $([char]0x1b)[91m×"
Some Links:
❌ https://emojipedia.org/microsoft/windows-10-october-2018-update/cross-mark/
How can I get Mocha's Unicode output to display properly in a Windows console?
Ansi escape codes
The new Terminal allows change of the font size like other apps with CTRL+Wheel among other goodies.

Related

Determine background color of specific X,Y coordinate in a PowerShell window

Suppose I print 100 lines with random background colors in a PowerShell window. How can I determine the background color that is applied to a specific line and character after the fact?
I tried changing to a location and printing the console background color, but as I suspected, that displays the background color that is already set as the output default:
$pos = (Get-Host).UI.RawUI.CursorPosition
$pos.X = 10
$pos.Y = 10
(Get-Host).UI.RawUI.CursorPosition = $pos
Write-Host (Get-Host).UI.RawUI.BackgroundColor
As PetSerAl pointed out in the comments, $Host.UI.RawUI.GetBufferContents is able to get the contents of arbitrary ranges from the buffer, including colors. I wrapped it in a function which I'll probably be using for this:
function Get-ColorsAtPosition {
Param(
[Parameter(Mandatory=$true)]
[int]$x,
[Parameter(Mandatory=$true)]
[int]$y
)
$colors = $Host.UI.RawUI.GetBufferContents(#{
Left=$x; Right=$x; Top=$y; Bottom=$y;
})
return #{
ForegroundColor=$colors.ForegroundColor;
BackgroundColor=$colors.BackgroundColor;
}
}
Usage:
$c = Get-ColorsAtPosition -x 3 -y 5
$c.ForegroundColor # White
$c.BackgroundColor # Blue
Remember that the -x and -y are zero-indexed.

Using powershell to change an image in MS office publisher

I am creating a powershell script that will auto generate publisher files for wristbands. On the Wristband is a QR code and a few other details to personally identify the wearer. I currently have a template file set up, a script that copies this, renames it, and edits some of the text on the page.
What I need it the script to change the placeholder image in the template to a QR code image, the data in the QR is only every going to be from a set amount of images (one of 1800), all have been generated and named to match up with the names used in Powershell.
Has anyone changed an image in MS Publisher using powershell before? Below is the code I currently have.
$CurrentMember = "M001S001"
$CurrectDocumet = "C:\Users\Rob\Documents\DistrictCamp2017\GeneratedFiles\" + $CurrentMember + ".pub"
copy-item "C:\Users\Rob\Documents\DistrictCamp2017\TemplateWristband.pub" "C:\Users\Rob\Documents\DistrictCamp2017\GeneratedFiles"
Rename-Item "C:\Users\Rob\Documents\DistrictCamp2017\GeneratedFiles\TemplateWristband.pub" "$CurrentMember.pub"
Add-Type -AssemblyName Microsoft.Office.Interop.Publisher
$Publisher = New-Object Microsoft.Office.Interop.Publisher.ApplicationClass
$OpenDoc = $Publisher.Open("C:\Users\Rob\Documents\DistrictCamp2017\GeneratedFiles\M001S001.pub")
###Replace Barcode and text
$pbReplaceScopeAll = 2
$OpenDoc.Find.Clear()
$OpenDoc.Find.FindText = "DEFAULT"
$OpenDoc.Find.ReplaceWithText = $CurrentMember
$OpenDoc.Find.ReplaceScope = "2" #$pbReplaceScopeAll
$OpenDoc.Find.Execute()
$OpenDoc.Save()
$OpenDoc.Close()
$Publisher.quit()
The image in the template document is currently a blank 145*145 pixel square, to be replaced by the appropriate QR code image, dependant on the value of $CurrentMember. I haven't yet written anything to try and change the image as I cannot find anything online, anything I search for seems to return results about Azure publisher server images.
Many thanks,
Rob
The easiest way is probably to get the shape by index, then add a new picture in its place, then remove the original shape:
Sub ReplaceFirstShapeWithImage()
Dim oPage As Page
Dim oShape As Shape
Dim newImage As Shape
Set oPage = Application.ActiveDocument.ActiveView.ActivePage
Set oShape = oPage.Shapes(1)
''https://msdn.microsoft.com/en-us/library/office/ff940072.aspx
Set newImage = oPage.Shapes.AddPicture("C:\Users\johanb\Pictures\X.png", msoFalse, msoTrue, oShape.Left, oShape.Top, oShape.Width, oShape.Height)
oShape.Delete
End Sub
This should help you find the right index
Sub GetIndexOfSelectedShape()
If Application.Selection.ShapeRange.Count = 0 Then
MsgBox "Please select a shape first"
Exit Sub
End If
Dim oShape As Shape
Dim oLoopShape As Shape
Dim i As Long
Set oShape = Application.Selection.ShapeRange(1)
For i = 1 To oShape.Parent.Shapes.Count
Set oLoopShape = oShape.Parent.Shapes(i)
If oLoopShape Is oShape Then
MsgBox oShape.Name & " has index " & i
End If
Next i
End Sub
Unfortunately I can't use PowerShell right now, but this VBA code should help you with the object model

Why does my value change when I am not resetting it?

I have the following example exhibiting the problem I'm struggling to resolve.
In the toy example, I have an array #actors with two levels.
I also have an array of hashes #people which I am using to 'look up' properties of the people in #actors.
The output of the program should be:
blue, blue cat, cat
red, red dog, dog
blue, blue cat, cat
red, red dog, dog
but instead I'm getting:
blue, cat cat, cat
red, dog dog, dog
blue, cat cat, cat
red, dog dog, dog
That is, it seems that in setting $favanim[$i][$j] I seem to be also overwriting the value of $favcols[$i][$j].
I suspect that for some reason the fact that #actors is a 2-dimensional array means that assignments via = are as references rather than as values, though I don't know why or how to stop it.
Please help!
The toy program is here: (I apologise if it can be simplified whilst still exhibiting the problem - it has taken me most of the afternoon to strip it down to this)
#!/usr/bin/perl -w
my #people = ();
$people[0]{'alternative full names for regexp'} = 'matthew smith|matt smith';
$people[1]{'alternative full names for regexp'} = 'david tennant|dave tennant';
$people[0]{'fav colour'} = 'red';
$people[1]{'fav colour'} = 'blue';
$people[0]{'fav animal'} = 'dog';
$people[1]{'fav animal'} = 'cat';
my #actors = ();
$actors[0][0] = 'David Tennant';
$actors[0][1] = 'Matt Smith';
$actors[1][0] = 'David Tennant';
$actors[1][1] = 'Matt Smith';
my #favcols = #actors;
my #favanim = #actors;
for ($i=0; $i<2; $i++) {
for ($j=0; $j<2; $j++) {
my #matching_people = grep{$actors[$i][$j] =~ m/^$_->{'alternative full names for regexp'}$/i} #people;
$favcols[$i][$j] = $matching_people[0]{'fav colour'};
$favanim[$i][$j] = $matching_people[0]{'fav animal'};
print "$matching_people[0]{'fav colour'}, $favcols[$i][$j] $matching_people[0]{'fav animal'}, $favanim[$i][$j]\n";
}
}
Try using
#favcols = map { [#$_] } #actors;
#favanim = map { [#$_] } #actors;
Deep copy vs shallow copy.
The problem is that you are initialising #favcols and #favanim by copying the contents of #people, which contains two array references
That sets $favcol[0] and $favanim[0] to a reference to the same array, [ 'David Tennant', 'Matt Smith' ], so when you modify $favcols[$i][$j] and then $favanim[$i][$j] you are overwriting the same array element
I don't see any reason to initialise your arrays at all, and if you declare them as just
my (#favcols, #favanim);
then you will find that your program does what you expect
By the way, you must always use strict, and use warnings is preferable to -w on the command line

Adding specific letters to a string MATLAB

I'm a neuroscience/biomedical engineering major struggling with this whole MATLAB programming ordeal and so far, this website is the best teacher available to me right now. I am currently having trouble with one of my HW problems. What I need to do is take a phrase, find a specific word in it, then take a specific letter in it and increase that letter by the number indicated. In other words:
phrase = 'this homework is so hard'
word = 'so'
letter = 'o'
factor = 5
which should give me 'This homework is sooooo hard'
I got rid of my main error, though I really don;t know how. I exited MATLAB, then got back into it. Lo and behold, it magically worked.
function[out1] = textStretch(phrase, word, letter, stretch)
searchword= strfind(phrase, word);
searchletter strfind(hotdog, letter); %Looks for the letter in the word
add = (letter+stretch) %I was hoping this would take the letter and add to it, but that's not what it does
replace= strrep(phrase, word, add) %This would theoretically take the phrase, find the word and put in the new letter
out1 = replace
According to the teacher, the ones() function might be useful, and I have to concatenate strings, but if I can just find it in the string and replace it, why do I need to concatenate?
Since this is homework I won't write the whole thing out for you but you were on the right track with strfind.
a = strfind(phrase, word);
b = strfind(word, letter);
What does phrase(1:a) return? What does phrase(a+b:end) return?
Making some assumptions about why your teacher wants you to use ones:
What does num = double('o') return?
What does char(num) return? How about char([num num])?
You can concatenate strings like this:
out = [phrase(1:a),'ooooo',phrase(a+b:end)];
So all you really need to focus on is how to get a string which is letter repeated factor times.
If you wanted to use strrep instead you would need to give it the full word you are searching for and a copy of that word with the repeated letters in:
new_phrase = strrep(phrase, 'so', 'sooooo');
Again, the issue is how to get the 'sooooo' string.
See if this works for you -
phrase_split = regexp(phrase,'\s','Split'); %// Split into words as cells
wordr = cellstr(strrep(word,letter,letter(:,ones(1,factor))));%// Stretched word
phrase_split(strcmp(phrase_split,word)) = wordr;%//Put stretched word into place
out = strjoin(phrase_split) %// %// Output as the string cells joined together
Note: strjoin needs a recent MATLAB version, which if unavailable could be obtained from here.
Or you can just use a hack obtained from the m-file itself -
out = [repmat(sprintf(['%s', ' '], phrase_split{1:end-1}), ...
1, ~isscalar(phrase_split)), sprintf('%s', phrase_split{end})]
Sample run -
phrase =
this homework is so hard and so boring
word =
so
letter =
o
factor =
5
out =
this homework is sooooo hard and sooooo boring
So, just wrap the code into a function wrapper like this -
function out = textStretch(phrase, word, letter, factor)
Homework molded edit:
phrase = 'this homework is seriously hard'
word = 'seriously'
letter = 'r'
stretch = 6
out = phrase
stretched_word = letter(:,ones(1,stretch))
hotdog = strfind(phrase, word)
hotdog_st = strfind(word,letter)
start_ind = hotdog+hotdog_st-1
out(start_ind+stretch:end+stretch-1) = out(start_ind+1:end)
out(hotdog+hotdog_st-1:hotdog+hotdog_st-1+stretch-1) = stretched_word
Output -
out =
this homework is serrrrrriously hard
As again, use this syntax to convert to function -
function out = textStretch(phrase, word, letter, stretch)
Well Jessica first of all this is WRONG, but I am not here to give you the solution. Could you please just use it this way? This surely run.
function main_script()
phrase = 'this homework is so hard';
word = 'so';
letter = 'o';
factor = 5;
[flirty] = textStretchNEW(phrase, word, letter, factor)
end
function [flirty] = textStretchNEW(phrase, word, letter, stretch)
hotdog = strfind(phrase, word);
colddog = strfind(hotdog, letter);
add = letter + stretch;
hug = strrep(phrase, word, add);
flirty = hug
end

strfind split keyword within paragraph

After the output of keywords in URL, how do I check whether the keywords exist in the content of the page like the content below, if yes then return 1, else return 0. There is strfind at there, but I do not have idea why it cannot work
str = 'http://en.wikipedia.org/wiki/hostname'
Paragraph = 'hostname From wikipedia, the free encyclopedia Jump to: navigation, search In computer networking, a hostname (archaically nodename .....'
SplitStrings = regexp(str,'[/.]','split')
for it = SplitStrings
c( it{1} ) = strfind(Paragraph, it{1} )
end
SplitStrings = {};
feature11=(cellfun(#(n) isempty(n), strfind(Paragraph, SplitStrings{1})))
I can do with the below code 4 checking whether 'https' exist or not. But, how to modify the 'SplitString' into 'B6'?
str = 'https://en.wikipedia.org/wiki/hostname'
A6 = regexp(str,'\w*://','match','once')
B6 = {'https'};
feature6=(cellfun(#(n) isempty(n), strfind(A6, B6{1})))
It is absolutely not clear to me what you want to do here...
I suspect it is this:
str = 'http://en.wikipedia.org/wiki/hostname';
haystack = 'hostname From wikipedia, the free encyclopedia Jump to: navigation, search In computer networking, a hostname (archaically nodename .....';
needles = regexp(str,'[:/.]*','split') %// note the different search string
%// What I think you want to do
~cellfun('isempty', regexpi(haystack, needles, 'once'))
Results:
needles =
'http' 'en' 'wikipedia' 'org' 'wiki' 'hostname'
ans =
0 1 1 0 1 1
but if this is not the case, please edit your question and include your desired outputs for some example inputs.
EDIT
OK, so if I understand you corretly now, you want whole words and not partial matches. You must tell this to regexp, in the following way:
%// NOTE: these metacharacters indicate that match is to occur
%// at beginning AND end of word (so whole words only)
needles = strcat('\<', regexpi(str,'[:/.]*','split'), '\>')
%// Search for these words in the paragraph
~cellfun('isempty', regexpi(haystack, needles, 'once'))
You can try this
f=#(str) isempty(strfind(Paragraph,str))
cellfun(f,SplitStrings)
This should get whole words. The key is parsing the variable Paragraph to get them
SplitParagraph=regexp(Paragraph,'[ ,:.()]','split');
I=ismember(SplitStrings,SplitParagraph);
SplitStrings(I)