How to set kern Persian Numbers in SwiftUI - swiftui

I'm trying to kern Persian numbers but .kerning() doesn't work.
Do you know any another way to set kern in persian numbers?
Text(250000, format: .number)
.kerning(5)
Text("250000")
.kerning(5)
Text(25000.asCurrencyFa)
.kerning(5)
This is my extension how I format the numbers:
extension Int {
var asCurrencyFa: String {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.locale = Locale(identifier: "fa_IR")
formatter.currencySymbol = ""
return formatter.string(from: self as NSNumber)!
}
}

Kerning (really "expansion" here since this isn't really kerning IMO) is a function of the font, and the default system font (.SFUI-Regular, but I'm pretty sure it's actually SF Arabic) does not appear to support expanding Persian digits. It will expand Persian letters somewhat. For example, فارسی, with .kern(10) displays this way vs "normal."
That said, there are fonts that support expanding Persian digits. For example, Geeza Pro:
let ctFont = CTFontCreateWithName("GeezaPro" as CFString, 16, nil)
...
Text(25000.asCurrencyFa)
.font(Font(ctFont))
Text(25000.asCurrencyFa)
.font(Font(ctFont))
.kerning(10)
One approach to get the "look" is to add HAIR SPACE U+200A between all the characters:
return formatter.string(from: self as NSNumber)!
.map(String.init).joined(separator: "\u{200A}")
This will be a little wider than expected because the HAIR SPACE has width of its own, plus there are two "kernings" per digit pair rather than one. But I do believe it will work with every font. I tried using various zero-width spaces, but they're mostly ignored, except around the comma.

Related

How to also populate "N/A" with If AND function in Google Sheets

My current formula populates Missed, Meets, Nearly Meets, and Exceeds. But I can't seem to figure out how to include "N/A" or create a blank cell in the formula.
My forumla so far:
=if(AND(L40>=14.5, L40<=16.4),"Nearly Meets", if(AND(L40>=4.5, L40<=14.4),"Meets", if(AND(L40>=15.5),"Missed","Exceeds")))
So, if L40 has any range of these number, M40 populates any of these Texts. How can I add to the formula so a blank cell populates "N/A" . Or, entering "TBD" in a cell leaves it blank or populates "N/A"
I'd rather use IFS formula or VLOOKUP here. It's short and clear.
=ifna(vlookup(B2,F2:G6,2,true),"value not found")
On a side you make a table of requirements and go through it using vlookup.
If you have no space anywhere in your sheet, you can also include value table into your formula using curly brackets:
=ifna(vlookup(B2,{0,"Missed";4.5,"Nealry Meets";14.4,"Meets";15.5,"Exceeds";"","Empty"},2,true),"value not found")
For values outside the set you can use IFNA formula.
If you use indentation before writing the final formula, it looks like this:
if(AND(L40>4.4; L40<=16.4){
"Nearly Meets";
}
else if(AND(L40>=4.5; L40<=14.4){
"Meets";
}
else if(L40>16.4){
"Missed";
}
else if(L40 = ""){
"N/A";
}
else {
"EXCEEDS"
}
Notice that I didn't use the condition if(L40<4.5), because a blank cell can be interpreted as 0, which is always less than 4.5, so you would never reach the N/A condition. By better determining your ranges, it gets easier to escape the exceeds case. It may not be your case, but if you had 2 or more digits after the decimal point, it could give you an unexpected result.
That said, you can now use the formula as
=if(AND(L40>4.4, L40<=16.4), "Nearly Meets", if(AND(L40>=4.5, L40<=14.4), "Meets", if(L40>16.4, "Missed", if(L40 = "", "N/A", "EXCEEDS"))))

NLP with less than 20 Words on google cloud

According to this documentation: the classifyText method requires at least 20 words.
https://cloud.google.com/natural-language/docs/classifying-text#language-classify-content-nodejs
If I send in less than 20 words I get this no matter how clear the content is:
Invalid text content: too few tokens (words) to process.
Looking for a way to force this without disrupting the NLP too much. Are there neutral vector words that can be appended to short phrases that would allow the classifyText to process anyways?
ex.
async function quickstart() {
const language = require('#google-cloud/language');
const client = new language.LanguageServiceClient();
//less than 20 words. What if I append some other neutral words?
//.. a, of , it, to or would it be better to repeat the phrase?
const text = 'The Atlanta Braves is the best team.';
const document = {
content: text,
type: 'PLAIN_TEXT',
};
const [classification] = await client.classifyText({document});
console.log('Categories:');
classification.categories.forEach(category => {
console.log(`Name: ${category.name}, Confidence: ${category.confidence}`);
});
}
quickstart();
The problem with this is you're adding bias no matter what kind of text you send.
Your only chance is to fill up your string up to the minimum word limit with empty words that will be filtered out by the preprocessor and tokenizer before they go to the neural network.
I would try to add a string suffix at the end of the sentence with just stopwords from NLTK like this:
document.content += ". and ourselves as herserf for each all above into through nor me and then by doing"
Why the end? Because usually text has more information at the beginning.
In case Google does not filter stopwords behind the scenes (which I doubt), this would add just white noise where the network has no focus or attention.
Remember: DO NOT add this string when you have enough words because you are billed for 1K character blocks before they are filtered.
I would also add that string suffix to sencences in your train/test/validation set that have less than 20 words and see how it works. The network should learn to ignore the whole sentence.

Regex for XAML Formatting

I'm attempting to build a PowerShell CmdLet that can parse and cleanly reformat a chunk of XAML or any other markup language.
So far, I've had to build an assortment of CmdLet's so that I can get the correct information to put into this thing (for indentation, counts, items, child items, etc, so forth...)
What I'm attempting to do is to collect ALL of the properties and values in a set of XAML/HTML, etc, and then once I have the lengths of all those variables, I can then start to chunk them out and properly format them so that they all output down a straight line. It may not make a super amount of sense as I describe it? So, here's an example.
<Window xmlns = 'http://schemas.microsoft.com/winfx/2006/xaml/presentation'
xmlns:x = 'http://schemas.microsoft.com/winfx/2006/xaml'
Title = 'Window Title'
Height = '600'
MinHeight = '600'
Width = '800'
MinWidth = '800'
BorderBrush = 'Black'
ResizeMode = 'CanResize'
HorizontalAlignment = 'Center'
WindowStartupLocation = 'CenterScreen'>
The reason I am attempting to build this, is so that I can programmatically save the instructions to a smaller footprint. So, instead of... having fluctuating numbers for each line and item and the end result looking like this...
<Window xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
xmlns:x = 'http://schemas.microsoft.com/winfx/2006/xaml' Title = 'Window Title' Height = '600'
MinHeight = '600' Width = '800' MinWidth = '800' BorderBrush = 'Black' ResizeMode = 'CanResize'
HorizontalAlignment = 'Center' WindowStartupLocation = 'CenterScreen'>
...I then have a set of instructions that can vectorize the content of the XAML, so that it has a pattern and less randomness. Sure, the line count might get expanded quite a bit, but there's no need to be concerned with that if all it is doing is expanding into RAM. Which is the point of it...
At any rate, the code that I am having trouble with is essentially a way to preserve the spacing between the quoted objects. I feel like I'm beating my head against a wall trying to get this to work correctly when I know it's a matter of Regex ...
I've posted the code I'm talking about via this link.
https://github.com/secure-digits-plus-llc/FightingEntropy/blob/master/Format-XAML.ps1
Lines 43-147
It is a script block, and testing with it requires a Xaml Here String.
Any suggestions would be appreciated. I'm not much of a Regex fan, I understand some basics to it but I'm not that great with it yet.
-MC
Found the answer I was looking for.
Not the most eloquent way to solve the issue I was having, but it works.
"(?<=\').+?(?=\')"
When the lines are split, and you want to preserve the spacing within the quotes, then you need something like this.
I was attempting to iterate through a do loop until the array/string contained (2) single quotes, but what was happening was... 'oh. I thought you wanted to match 'adbhjikvgrfe' with '21345rfs'.
No regex. Wasn't looking to match that. sigh.
Then it was taking the spacing out between the quotes.
sigh
I gotta say... anyone who truly writes good programming...? Well, I tip my hat off to you good sir/ma'am... because... it's a frustrating job. For certain.

How to indent the first line of a multiline paragraph using jspdf

I need to print a multiline paragraph with the first line indented using jsPDF.
I splitted my text with .splitTextToSize function using option textIndent.
Then used .text to render the result. See code below :
doc = mbjsPDF({
orientation: 'portrait',
unit: 'mm',
format: 'a4'
});
var text = "To be, or not to be, that is the question: Whether 'tis nobler in the mind to suffer The slings and arrows of outrageous fortune";
var textTab = doc.splitTextToSize(text, 100, {textIndent: 30});
doc.text(10, 20, textTab);
doc.save('test.pdf');
Actual result:
To be, or not to be, that is
the question: Whether 'tis nobler in the
mind to suffer The slings and arrows of
outrageous fortune
Expected result: (I want the first line shifted by 30mm)
To be, or not to be, that is
the question: Whether 'tis nobler in the
mind to suffer The slings and arrows of
outrageous fortune
Not sure about option textIndent, but if you have only one paragraph, you may simply add a tab to the beginning of that paragraph.
var textTab = doc.splitTextToSize(' ' + text, 100);
I mainly use jsPDF to convert HTML to PDF. If you just want to convert plain text, maybe you can consider pdfmake as well. It has an auto page break and is easy to add the margin, etc.
<script src="http://pdfmake.org/build/pdfmake.min.js"></script>
<script src="http://pdfmake.org/build/vfs_fonts.js"></script>
<script>
function print() {
// open the PDF in a new window
pdfMake.createPdf(dd).open();
}
var dd = {
content: [{
leadingIndent: 30,
lineHeight: 1.5, // optional
text: "To be, or not to be, that is the question: Whether 'tis nobler in the mind to suffer The slings and arrows of outrageous fortune"
}]
}
</script>
textIndent is used for the space between lines, it's really confusing!
You could make the first line a seperate text component. Than you can change the x parameter of the Text class.

Flex - Actionscript - RegExp - Retrieve Specific Data From a String

I have been messing with this for a while now, and decided to post on here to see if anyone could help out. I even messed around with the RegExr tool (with no luck):
http://gskinner.com/RegExr
Anyway, I have a String that contains the verbiage (without the quotes):
"13.5 to 14.1"
I need to create a var with the first number: 13.5 and a var with the second number: 14.1
So I want the following result:
var firstVal:String = 13.5;
var secondVal:String = 14.1;
I got it to work by doing the following for the first number:
var lowRegExp:RegExp=/\d[0-9].\d[0-9]/;
And for the second number I did this:
var highRegExp:RegExp=/\d[0-9].\d[0-9]$/;
My problem here is that I will not know the format of the String. It could also look like this (two digits trailing the decimal):
13.57 to 14.10
So I need to make sure that it works using the following combinations:
13.50 to 14.1, 13.5 to 14.10, 3.50 to 4.10, 3.5 to 4.1 (all combinations must work)
Any help is much appreciated!
Here is what I got to work. I am not sure how clean this is, and I am not a fan of hard coding, but it works for all scenarios. If someone knows a clean way to do this, please let me know.
var myString:String="13.5 to 14.1";
var firstVal:String=myString.substring(0, myString.search(" to "));
var secondVal:String=myString.substring((myString.search(" to ") + 4));
Should be pretty straight forward, you want the following:
- Any # of digits, followed by a period literal, followed by any # of digits.
Pattern: \d+\.\d+
So use something similar:
var mystr:String = "15.4 to 153.93";
var tokens:Array = mystr.match(/\d+\.\d+/g);
Also, I have gotten myself in the habit of using regexpal.com which is way faster than iterative testing in your application. ;)