Swift 3: How to get language code from a country code? - ios
I want to get the main language of a country. For example: "US" -> "en" or "VN" -> "vi" In Swift 3, are there any ways to do this?
The system has a list of common locales that include both a language and region. You can use this to get common languages for a region. There is no concept of a main language in a Locale.
func commonLanguages(for region:String) -> [String] {
return Locale.availableIdentifiers
.map { Locale(identifier:$0) }
.filter { $0.regionCode == region }
.map { $0.languageCode ?? "??" }
}
You can use a predefined language code list to identify the language code
let array: [String] = [
"af-ZA",
"am-ET",
"ar-AE",
"ar-BH",
"ar-DZ",
"ar-EG",
"ar-IQ",
"ar-JO",
"ar-KW",
"ar-LB",
"ar-LY",
"ar-MA",
"arn-CL",
"ar-OM",
"ar-QA",
"ar-SA",
"ar-SY",
"ar-TN",
"ar-YE",
"as-IN",
"az-Cyrl-AZ",
"az-Latn-AZ",
"ba-RU",
"be-BY",
"bg-BG",
"bn-BD",
"bn-IN",
"bo-CN",
"br-FR",
"bs-Cyrl-BA",
"bs-Latn-BA",
"ca-ES",
"co-FR",
"cs-CZ",
"cy-GB",
"da-DK",
"de-AT",
"de-CH",
"de-DE",
"de-LI",
"de-LU",
"dsb-DE",
"dv-MV",
"el-GR",
"en-029",
"en-AU",
"en-BZ",
"en-CA",
"en-GB",
"en-IE",
"en-IN",
"en-JM",
"en-MY",
"en-NZ",
"en-PH",
"en-SG",
"en-TT",
"en-US",
"en-ZA",
"en-ZW",
"es-AR",
"es-BO",
"es-CL",
"es-CO",
"es-CR",
"es-DO",
"es-EC",
"es-ES",
"es-GT",
"es-HN",
"es-MX",
"es-NI",
"es-PA",
"es-PE",
"es-PR",
"es-PY",
"es-SV",
"es-US",
"es-UY",
"es-VE",
"et-EE",
"eu-ES",
"fa-IR",
"fi-FI",
"fil-PH",
"fo-FO",
"fr-BE",
"fr-CA",
"fr-CH",
"fr-FR",
"fr-LU",
"fr-MC",
"fy-NL",
"ga-IE",
"gd-GB",
"gl-ES",
"gsw-FR",
"gu-IN",
"ha-Latn-NG",
"he-IL",
"hi-IN",
"hr-BA",
"hr-HR",
"hsb-DE",
"hu-HU",
"hy-AM",
"id-ID",
"ig-NG",
"ii-CN",
"is-IS",
"it-CH",
"it-IT",
"iu-Cans-CA",
"iu-Latn-CA",
"ja-JP",
"ka-GE",
"kk-KZ",
"kl-GL",
"km-KH",
"kn-IN",
"kok-IN",
"ko-KR",
"ky-KG",
"lb-LU",
"lo-LA",
"lt-LT",
"lv-LV",
"mi-NZ",
"mk-MK",
"ml-IN",
"mn-MN",
"mn-Mong-CN",
"moh-CA",
"mr-IN",
"ms-BN",
"ms-MY",
"mt-MT",
"nb-NO",
"ne-NP",
"nl-BE",
"nl-NL",
"nn-NO",
"nso-ZA",
"oc-FR",
"or-IN",
"pa-IN",
"pl-PL",
"prs-AF",
"ps-AF",
"pt-BR",
"pt-PT",
"qut-GT",
"quz-BO",
"quz-EC",
"quz-PE",
"rm-CH",
"ro-RO",
"ru-RU",
"rw-RW",
"sah-RU",
"sa-IN",
"se-FI",
"se-NO",
"se-SE",
"si-LK",
"sk-SK",
"sl-SI",
"sma-NO",
"sma-SE",
"smj-NO",
"smj-SE",
"smn-FI",
"sms-FI",
"sq-AL",
"sr-Cyrl-BA",
"sr-Cyrl-CS",
"sr-Cyrl-ME",
"sr-Cyrl-RS",
"sr-Latn-BA",
"sr-Latn-CS",
"sr-Latn-ME",
"sr-Latn-RS",
"sv-FI",
"sv-SE",
"sw-KE",
"syr-SY",
"ta-IN",
"te-IN",
"tg-Cyrl-TJ",
"th-TH",
"tk-TM",
"tn-ZA",
"tr-TR",
"tt-RU",
"tzm-Latn-DZ",
"ug-CN",
"uk-UA",
"ur-PK",
"uz-Cyrl-UZ",
"uz-Latn-UZ",
"vi-VN",
"wo-SN",
"xh-ZA",
"yo-NG",
"zh-CN",
"zh-HK",
"zh-MO",
"zh-SG",
"zh-TW",
"zu-ZA"
];
var countryCode: String = "US";
for (index, languageCode) in array.enumerated() {
let languageComponent: [String] = languageCode.components(separatedBy: "-");
let lastElement = languageComponent[languageComponent.count - 1];
if (lastElement == countryCode) {
print(languageCode);
break;
}
}
Related
Text hyperlink hashtags(#) and mentions(#) in Jetpack Compose?
Text hyperlink hashtags(#) and mentions(#) in Jetpack Compose? #Composable fun HashtagsAndMentions() { val colorScheme = MaterialTheme.colorScheme val primaryStyle = SpanStyle(color = colorScheme.primary) val textStyle = SpanStyle(color = colorScheme.onBackground) val annotatedString = buildAnnotatedString { withStyle(style = textStyle) { append("I am ") } pushStringAnnotation(tag = "hashtags", annotation = "hashtags") withStyle(style = primaryStyle) { append(text = "#hashtags") } pop() withStyle(style = textStyle) { append(" and ") } pushStringAnnotation(tag = "mentions", annotation = "mentions") withStyle(style = primaryStyle) { append(text = "#mentions") } pop() withStyle(style = textStyle) { append(" in Jetpack Compose.") } } ClickableText( onClick = { annotatedString.getStringAnnotations("hashtags", it, it).firstOrNull()?.let { } annotatedString.getStringAnnotations("mentions", it, it).firstOrNull()?.let { } }, text = annotatedString, style = MaterialTheme.typography.bodyLarge, modifier = Modifier.padding(16.dp)) } #Preview #Composable fun PreviewTest() { HashtagsAndMentions() } The above are fixed tags, how to dynamically identify and link? ideas String to array val string = "I am #hashtags and #mentions in Jetpack Compose." val array = arrayOf("I am ", "#hashtags", " and ", "#mentions", "in Jetpack Compose.")
Here is an available hashtag and mention link. Many thanks to #cyberpunk_unicorn for the idea, unfortunately his answer is not available, but I marked it anyway. I refactored his code to ensure that it is runnable, concise enough, and very helpful to those who need it later. This is a very flexible link scheme, you can add support for mobile phone numbers, emails, links, etc., as long as your regular expressions are correct, these links can be correctly identified. #Composable fun HashtagsMentionsTextView(text: String, modifier: Modifier = Modifier, onClick: (String) -> Unit) { val colorScheme = MaterialTheme.colorScheme val textStyle = SpanStyle(color = colorScheme.onBackground) val primaryStyle = SpanStyle(color = colorScheme.blue) val hashtags = Regex("((?=[^\\w!])[##][\\u4e00-\\u9fa5\\w]+)") val annotatedStringList = remember { var lastIndex = 0 val annotatedStringList = mutableStateListOf<AnnotatedString.Range<String>>() // Add a text range for hashtags for (match in hashtags.findAll(text)) { val start = match.range.first val end = match.range.last + 1 val string = text.substring(start, end) if (start > lastIndex) { annotatedStringList.add( AnnotatedString.Range( text.substring(lastIndex, start), lastIndex, start, "text" ) ) } annotatedStringList.add( AnnotatedString.Range(string, start, end, "link") ) lastIndex = end } // Add remaining text if (lastIndex < text.length) { annotatedStringList.add( AnnotatedString.Range( text.substring(lastIndex, text.length), lastIndex, text.length, "text" ) ) } annotatedStringList } // Build an annotated string val annotatedString = buildAnnotatedString { annotatedStringList.forEach { if (it.tag == "link") { pushStringAnnotation(tag = it.tag, annotation = it.item) withStyle(style = primaryStyle) { append(it.item) } pop() } else { withStyle(style = textStyle) { append(it.item) } } } } ClickableText( text = annotatedString, style = MaterialTheme.typography.bodyLarge, modifier = modifier, onClick = { position -> val annotatedStringRange = annotatedStringList.first { it.start < position && position < it.end } if (annotatedStringRange.tag == "link") onClick(annotatedStringRange.item) } ) } #Preview #Composable fun PreviewTest() { val string = "I am #hashtags or #hashtags# and #mentions in Jetpack Compose. I am #hashtags or #hashtags# and #mentions in Jetpack Compose. 这是在 Jetpack Compose 中的一个 #标签 和 #提及 的超链接。 这是在 Jetpack Compose 中的一个 #标签 和 #提及 的超链接。" HashtagsMentionsTextView(string, Modifier.padding(16.dp)) { println(it) } } preview effect
Metric math alarms: How can I use a for_each expression to loop over metrics within a dynamic block?
I am trying to create dynamic metric math alarms, that are configurable with a JSON. I am struggling with looping over the metric alarm with a for_each expression as this is a loop within a loop. Here is an example of what I am trying to do: resource "aws_cloudwatch_metric_alarm" "Percentage_Alert" { for_each = var.percentage_error_details locals { alarm_details = each.value } alarm_name = "${terraform.workspace}-${each.key}" comparison_operator = local.alarm_details["Comparison_Operator"] evaluation_periods = "1" threshold = local.alarm_details["Threshold"] metric_query { id = "e1" expression = local.alarm_details["Expression"] label = local.alarm_details["Label"] return_data = "true" } dynamic "metric_query" { for metric in each.value["Metrics"]{ id = metric.key metric_name = metric.value period = local.alarm_details["Period"] stat = local.alarm_details["Statistic"] namespace = local.full_namespace unit = "Count" } } } And this is the sample JSON { "locals": { "Name": { "Name": "metric_math", "Metrics": { "m1": "Sucess", "m2": "Failure" }, "Expression": "100*(m2/(m1+m2))", "Threshold" : 1, "Period": 25, "Priority": "critical", "Statistic": "Sum", "Label": "label", "Comparison_Operator": "GreaterThanOrEqualToThreshold" } } } And this is the error message i'm getting: Error: Invalid block definition On ../modules/cloudwatch/metriclogfilter/main.tf line 89: Either a quoted string block label or an opening brace ("{") is expected here. Any help would be much appreciated.
How to write a map to a YAML file in Dart
I have a map of key value pairs in Dart. I want to convert it to YAML and write into a file. I tried using YAML package from dart library but it only provides methods to load YAML data from a file. Nothing is mentioned on how to write it back to the YAML file. Here is an example: void main() { var map = { "name": "abc", "type": "unknown", "internal":{ "name": "xyz" } }; print(map); } Expected output: example.yaml name: abc type: unknown internal: name: xyz How to convert the dart map to YAML and write it to a file?
It's a bit late of a response but for anyone else looking at this question I have written this class. It may not be perfect but it works for what I'm doing and I haven't found anything wrong with it yet. Might make it a package eventually after writing tests. class YamlWriter { /// The amount of spaces for each level. final int spaces; /// Initialize the writer with the amount of [spaces] per level. YamlWriter({ this.spaces = 2, }); /// Write a dart structure to a YAML string. [yaml] should be a [Map] or [List]. String write(dynamic yaml) { return _writeInternal(yaml).trim(); } /// Write a dart structure to a YAML string. [yaml] should be a [Map] or [List]. String _writeInternal(dynamic yaml, { int indent = 0 }) { String str = ''; if (yaml is List) { str += _writeList(yaml, indent: indent); } else if (yaml is Map) { str += _writeMap(yaml, indent: indent); } else if (yaml is String) { str += "\"${yaml.replaceAll("\"", "\\\"")}\""; } else { str += yaml.toString(); } return str; } /// Write a list to a YAML string. /// Pass the list in as [yaml] and indent it to the [indent] level. String _writeList(List yaml, { int indent = 0 }) { String str = '\n'; for (var item in yaml) { str += "${_indent(indent)}- ${_writeInternal(item, indent: indent + 1)}\n"; } return str; } /// Write a map to a YAML string. /// Pass the map in as [yaml] and indent it to the [indent] level. String _writeMap(Map yaml, { int indent = 0 }) { String str = '\n'; for (var key in yaml.keys) { var value = yaml[key]; str += "${_indent(indent)}${key.toString()}: ${_writeInternal(value, indent: indent + 1)}\n"; } return str; } /// Create an indented string for the level with the spaces config. /// [indent] is the level of indent whereas [spaces] is the /// amount of spaces that the string should be indented by. String _indent(int indent) { return ''.padLeft(indent * spaces, ' '); } } Usage: final writer = YamlWriter(); String yaml = writer.write({ 'string': 'Foo', 'int': 1, 'double': 3.14, 'boolean': true, 'list': [ 'Item One', 'Item Two', true, 'Item Four', ], 'map': { 'foo': 'bar', 'list': ['Foo', 'Bar'], }, }); File file = File('/path/to/file.yaml'); file.createSync(); file.writeAsStringSync(yaml); Output: string: "Foo" int: 1 double: 3.14 boolean: true list: - "Item One" - "Item Two" - true - "Item Four" map: foo: "bar" list: - "Foo" - "Bar"
package:yaml does not have YAML writing features. You may have to look for another package that does that – or write your own. As as stopgap, remember JSON is valid YAML, so you can always write out JSON to a .yaml file and it should work with any YAML parser.
I ran into the same issue and ended up hacking together a simple writer: // Save the updated configuration settings to the config file void saveConfig() { var file = _configFile; // truncate existing configuration file.writeAsStringSync(''); // Write out new YAML document from JSON map final config = configToJson(); config.forEach((key, value) { if (value is Map) { file.writeAsStringSync('\n$key:\n', mode: FileMode.writeOnlyAppend); value.forEach((subkey, subvalue) { file.writeAsStringSync(' $subkey: $subvalue\n', mode: FileMode.writeOnlyAppend); }); } else { file.writeAsStringSync('$key: $value\n', mode: FileMode.writeOnlyAppend); } }); }
Dynamic cell color in jspdf autoTable?
Is it possible to define the cell color with a nested property of the object mapped to the table ? The JSON structure of the objects is : objects: [ { "agent": "agent_1", "days": { day_0: { "code": "ABC", "color": "#0062cc" }, day_1: { "code": "DEF", "color": "#a09494b2" } }, { [...] } ] I have a table defined like this : let columns = [ {title: "Agent", dataKey: "agent"}, {title: "january 1st", dataKey: "day_0"}, {title: "january 2nd", dataKey: "day_1"}] let rows = [ {agent: "agent_1", day_0: "ABC", day_1: "DEF"}, [...] ] All that works fine. But I'd like to set the color of each day cell dynamically, set with the color code of the corresponding object. Something like : createdCell: function(cell, data) { { cell.styles.fillColor = "day_0.color"; } } But I can't figure how to pass the data to the table. Is it possible ? Can displayProperty help in any way ?
EDIT: In this case it was that v2.3.4 of jspdf-autotable was needed Based on our comments discussion I think I understood your problem. You can try something like this (with the hexToRgb function from here) let columns = [{ title: "Agent", dataKey: "agent" }, { title: "january 1st", dataKey: "day_0" }, { title: "january 2nd", dataKey: "day_1" } ] let objects = [{ agent: "agent_1", day_0: { "code": "ABC", "color": "#00ff00" }, day_1: { "code": "DEF", "color": "#ff0000" } // etc }]; let doc = jsPDF() doc.autoTable(columns, objects, { createdCell: function(cell, data) { let hex = cell.raw.color if (hex) { let rgb = hexToRgb(hex) cell.styles.fillColor = rgb; cell.text = cell.raw.code } } }); doc.save('jhg.pdf') function hexToRgb(hex) { var bigint = parseInt(hex.replace('#', ''), 16); var r = (bigint >> 16) & 255; var g = (bigint >> 8) & 255; var b = bigint & 255; return [r, g, b]; } <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.4.1/jspdf.debug.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/2.3.4/jspdf.plugin.autotable.js"></script>
I just leave the answer here just in case anyone needs it. We can use the didParseCell hook. doc.autoTable({ head: [[..., color]], body: [[..., #ffffff], [..., #ff0000]], // pass hexa value to the cell didParseCell: function (HookData) { if (HookData.cell == undefined) return; // find cell taht contains the hexa value // the change the fillColor property // and set the cell value to empty var color = HookData.cell.text[0]; if (color.match(/^#[a-fA-F0-9]{3}([a-fA-F0-9]{3})/g) != null) { HookData.cell.styles.fillColor = hexToRgb(color); HookData.cell.text = []; } } }); Code to convert hexa to RGB: hexToRgb(hex) { var bigint = parseInt(hex.replace('#', ''), 16); var r = (bigint >> 16) & 255; var g = (bigint >> 8) & 255; var b = bigint & 255; return [r, g, b]; } Package version: jspdf : 2.5.1 jspdf-autotable :3.5.25
How to group non-empty lines with PEG.js
I'm trying to parse a categories file with PEG.js How can I group categories (set of non-empty lines followed by a blank line) stopwords:fr:aux,au,de,le,du,la,a,et,avec synonyms:en:flavoured, flavored synonyms:en:sorbets, sherbets en:Artisan products fr:Produits artisanaux < en:Artisan products fr:Gressins artisanaux en:Baby foods fr:Aliments pour bébé, aliment pour bébé, alimentation pour bébé, aliment bébé, alimentation bébé, aliments bébé < en:Baby foods fr:Céréales pour bébé, céréales bébé < en:Whisky fr:Whisky écossais es:Whiskies escoceses wikipediacategory:Q8718387 For now I can parse line by line with this code: start = stopwords* synonyms* category+ language_and_words = l:[^:]+ ":" w:[^\n]+ {return {language: l.join(''), words: w.join('')};} stopwords = "stopwords:" w:language_and_words "\n"+ {return {stopwords: w};} synonyms = "synonyms:" w:language_and_words "\n"+ {return {synonyms: w};} category_line = "< "? w:language_and_words "\n"+ {return w;} category = c:category_line+ {return c;} I got: { "language": "en", "words": "Artisan products" }, { "language": "fr", "words": "Produits artisanaux" } but I want (for each group): { { "language": "en", "words": "Artisan products" }, { "language": "fr", "words": "Produits artisanaux" } } I tried this too, but it doesn't group and I got \n at the beginning of some lines. category_line = "< "? w:language_and_words "\n" {return w;} category = c:category_line+ "\n" {return c;}
I found a partial solution: start = category+ word = c:[^,\n]+ {return c.join('');} words = w:word [,]? {return w.trim();} parent = p:"< "? {return (p !== null);} line = p:parent w:words+ "\n" {return {parent: p, words: w};} category = l:line+ "\n"? {return l;} I can parse this... < fr:a,b fr:aa,bb en:d,e,f fr:dd,ee, ffff and get grouped: [ [ {...}, {...} ], [ {...}, {...} ] ] But there is a problem with "lang:" at the beginning of each category, if I try to parse "lang:" my catégories are not grouped...
I find it's useful to break down iteratively the parse (problem decomposition, old-school à la Wirth). Here's a partial solution that I think gets you in the right direction (I didn't parse the Line elements of categories. start = stopwords synonyms category+ category "category" = category:(Line)+ categorySeparator { return category } stopwords "stopwords" = stopwordLine* stopwordLine "stopword line" = stopwordLine:StopWordMatch EndOfLine* { return stopwordLine } StopWordMatch = "stopwords:" match:Text { return match } synonyms "stopwords" = synonymLine* synonymLine "stopword line" = synonymLine:SynonymMatch EndOfLine* { return synonymLine } SynonymMatch = "synonyms:" match:Text { return match } Line "line" = line:Text [\n] { return line } Text "text" = [^\n]+ { return text() } EndOfLine "(end of line)" = '\n' EndOfFile = !. { return "EOF"; } categorySeparator "separator" = EndOfLine EndOfLine* / EndOfLine? EndOfFile My use of mixed case is arbitrary and not very stylish. There's also a way to save the solutions online: http://peg.arcanis.fr/2WQ7CZ/