How do I ignore lines that are commented out when parsing? - rebol

I have a PHP array that I'm parsing to get email addresses. Sometimes I'll want to comment an entry so I can use a different value for testing.
Here's an example of the array:
array('system.email' => array(
'to' => array(
'contactus' => 'contactus#example.com',
'newregistration' => 'newreg#example.com',
'requestaccess' => 'requestaccess#example.com',
// 'workflow' => 'workflow#example.com'
'workflow' => 'test_workflow#example.com'
)
));
Here's my PARSE rule:
parse read %config.php [
thru "'system.email'" [
thru "'to'" [thru "'workflow'" [thru "'" copy recipient-email to "'^/"]]
] to end
]
When I run that, the value of recipient-email is "workflow#example.com". How can I write my rule such that it ignores the line that begins with //?

A rule for eating up a comment line would look something like this:
spacer: charset reduce [tab cr newline #" "]
spaces: [some spacer]
any-spaces: [any spacer]
[any-spaces "//" thru newline]
You may judge how you want to do that with your current rule. Here's a somewhat messy way to deal with only comments in the array.
text: {array('system.email' => array(
'to' => array(
'contactus' => 'contactus#example.com',
'newregistration' => 'newreg#example.com',
'requestaccess' => 'requestaccess#example.com',
// 'workflow' => 'workflow#example.com'
'workflow' => 'test_workflow#example.com'
)
));}
list: []
spacer: charset reduce [tab cr newline #" "]
any-spaces: [any spacer]
comment-rule: [any-spaces "//" thru newline]
email-rule: [
thru "'"
copy name to "'" skip
thru "'"
copy email to "'"
thru newline
]
system-emails: [
thru "'system.email'" [
thru "to' => array("
some [
comment-rule |
email-rule (append list reduce [name email])
]
] to end
]
parse text system-emails
print list
This will result in a block of the names and emails from the array.
Maybe a more holistic approach could process the source and remove all comments before parsing. This is a function I have used in the past:
decomment: func [str [string!] /local new-str com comment-removing-rule] [
new-str: copy ""
com: [
"//"
thru newline
]
comment-removing-rule: [
some [
com |
copy char skip (append new-str char)
]
]
parse str comment-removing-rule
return new-str
]

Related

Laravel Excel: how to have all zeroes printed in a exported csv?

I'm exporting to csv using Laravel Excel.
I'm creating the out value as
'amount' => number_format(-$ai->final_invoice_amount, 2, ".", "")
But, for example for 204.00, in the exported csv I got only 204, without dot and leading zeroes.
I know that it's a valid number for a computer; but our client has a strict parser and it wants a 204.00 value.
I tried, but not works, to add an explicit cast to string, but it's useless because number_format outputs a string in any case
'amount' => (string)number_format(-$ai->final_invoice_amount, 2, ".", "")
Laravel Excel's Events give you access to PHPSpreadSheet under the hood.
https://docs.laravel-excel.com/3.1/exports/extending.html#events
With Events, you can apply the desired formatting to a cell or group of cells. It's easier to demonstrate than explain, so I have created a simple example.
<?php
namespace App\Export;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\BeforeSheet;
class SampleExport implements FromCollection, WithEvents
{
public function collection()
{
return collect([
[
'id' => 1,
'amount_1' => 100,
'amount_2' => 75.20,
'amount_3' => -23.10,
],
[
'id' => 2,
'amount_1' => -60,
'amount_2' => 50.40,
'amount_3' => 110,
],
]);
}
public function registerEvents(): array
{
return [
BeforeSheet::class => function (BeforeSheet $event) {
// format columns B-D to two decimal places
$event->sheet
->getDelegate()
->getStyle('B:D')
->getNumberFormat()
->setFormatCode('0.00');
},
];
}
}
This is the resulting CSV as output to a file.
"1","100.00","75.20","-23.10"
"2","-60.00","50.40","110.00"
NOTE: The values being formatted MUST BE A NUMBER TYPE! Attempting to format strings will not work.

How to add secondary text in elm?

I have a dropdown which shows text as moredetails with a keyboard-down-arrow, on clicking it expands and i can see the required fields. What i am trying to achieve is once on clicking the button when the secondary field expands i want to change the text to 'less details', i am able to achieve till like on expansion the keyboard downarrow mark becomes keyboard up arrow mark.
this is my code
Html.span
[ Attributes.class "details" ]
[ Html.a
[ Attributes.href "#", Events.onClick (ExpandDetails tx.id)]
[ Html.text "More detail"
, Html.i
[ Attributes.class "material-icons" ]
[ if expanded then
Html.text "keyboard_arrow_up"
else
Html.text "keyboard_arrow_down"
]
]
]
i am able to make it till if expands show downarrow but along with it i need text to change from more details to less details and on clicking less details it should be back to more details.
If I'm understanding correctly, you could define both the button and text in a let expression before the dropdown code. Something like:
let
( dropdownButton, dropdownText ) =
if expanded then
( "keyboard_arrow_up", "Less details" )
else
( "keyboard_arrow_down", "More details" )
in
Html.span [ Attributes.class "details" ]
[ Html.a
[ Attributes.href "#"
, Events.onClick (ExpandDetails tx.id)
]
[ Html.text dropdownText
, Html.i [ Attributes.class "material-icons" ]
[ Html.text dropdownButton ]
]
]
Here's an alternative.
Move the link into a function that takes the Strings as arguments.
viewDetails : Tx -> Bool -> Html Msg
viewDetails tx expanded =
let
lessOrMoreLink =
if expanded then
viewExpandLink "Less" "keyboard_arrow_up"
else
viewExpandLink "More" "keyboard_arrow_down"
in
Html.span
[ Attributes.class "details" ]
[ lessOrMoreLink tx.id ]
viewExpandLink : String -> String -> Int -> Html Msg
viewExpandLink txt arrow id =
Html.a
[ Attributes.href "#"
, Events.onClick (ExpandDetails id)
]
[ Html.text (txt ++ " details")
, Html.i
[ Attributes.class "material-icons" ]
[ Html.text arrow ]
]

Karate API framework - Validate randomly displayed items in response

I am using Karate API framework for the API automation and came across with one scenario, the scenario is when I am hitting a post call it gives me some json response and few of the items are having tags whereas few of them are showing tags as blank to get all the tags below is the feature file scenario line
* def getTags = get response.items[*].resource.tags
It is giving me response as
[
[
],
[
],
[
{
"tags" : "Entertainment"
}
],
[
],
[
{
"tags" : "Family"
}
],
As you can see out of 5 or 6 tags only 2 tags are having the value, so I want to capture if any tags value is showing or not. What would be the logic for the assertion considering these tags can all come as empty and sometimes with come with a string value. In above case "Family" & "Entertainment"
Thanks in advance !
* match each response.items[*].resource.tags == "##string"
This will validate that tags either doesn't exist or is a string.
I think you can use a second variable to strip out the empties, or maybe your original JsonPath should use .., you can experiment:
* def allowed = ['Music', 'Entertainment', 'Documentaries', 'Family']
* def response =
"""
[
[
],
[
],
[
{
"tags":"Entertainment"
}
],
[
],
[
{
"tags":"Family"
}
]
]
"""
* def temp = get response..tags
* print temp
* match each temp == "#? allowed.contains(_)"

Openrefine: split with regex gives strange result

I applied the GREL expression "value.split(/a/)" to some cells:
abcdef -> [ "", "bcdef" ]
bcdefa -> [ "bcdef" ]
badef -> [ "b", "def" ]
I can't understand why the first cell gives me a "" element in the resulting table. Is it a bug?
Thanks!
I don't know Java enough to comment on the source code for this function, but according to one of the developers of Open Refine this behavior is normal (edit : More details in Owen's comment, below). This is why there are other functions to split a string.
value.smartSplit(/a/), for example, gives a more consistent result when sep is at the begining or at the end of the string:
row value value.smartSplit(/a/)
1. abcdef [ "", "bcdef" ]
2. bcdefa [ "bcdef", "" ]
3. badef [ "b", "def" ]
This is the same result as using partition() with the omitfragment = true option enabled:
row value value.partition(/a/, true)
1. abcdef [ "", "bcdef" ]
2. bcdefa [ "bcdef", "" ]
3. badef [ "b", "def" ]

rebol parse rule with compose/deep and append function

This works great (thanks to Sunanda's suggestion How can I parse [a / b] ? syntax error in Rebol?):
attribute: copy []
class: copy []
definition-rule: compose/deep [some [set class word! 'is 'defined 'by
[some [copy attribute to (to-lit-word "/") thru (to-lit-word "/") ]]
copy attribute to end]]
parse [Customer is defined by First Name / Last Name / Email] definition-rule
but I now need to add some append instructions (append output class) and it doesn't work any more:
attribute: copy []
class: copy []
definition-rule: compose/deep [some [set class word! (append output class) 'is 'defined 'by
[some [copy attribute to (to-lit-word "/") thru (to-lit-word "/") ]]
copy attribute to end]]
parse [Customer is defined by First Name / Last Name / Email] definition-rule
The problem here is that the compose is eating all the expressions in parentheses. You are happy for it to eat the (to-lit-word "/") but you seriously do not want it to eat the (append output class) because that is intended for the parse dialect.
There is probably a cleverer approach, but this should work: remove the compose by doing the lit-word work outside of the parse rule...
attribute: copy []
class: copy []
output: copy ""
fs: to-lit-word "/" ;; define a forward slash lit-word
definition-rule: [
some [set class word! (append output class) 'is 'defined 'by [
some [copy attribute to fs thru fs]
]
copy attribute to end]
]
parse [Customer is defined by First Name / Last Name / Email] definition-rule
== true
I am not entirely sure what you are trying to do with this code, but it you want to extract the set of attributes at the end, then consider this change:
attribute: copy []
attributes: copy []
class: copy []
output: copy ""
fs: to-lit-word "/" ;; define a forward slash lit-word
definition-rule: [
some [set class word! (append output class) 'is 'defined 'by [
some [copy attribute to fs thru fs (append/only attributes attribute)]
]
copy attribute to end (append/only attributes attribute)]
]
parse [Customer is defined by First Name / Last Name / Email] definition-rule
print ["==" class mold attributes]
== Customer [[First Name] [Last Name] [Email]]
I repost code in comment as it isn't readable, what I wanted to do exactly was this:
attribute: copy []
class: copy []
fs: to-lit-word "/"
output: copy ""
definition-rule: [
some [set class word! (append output join class "|") 'is 'defined 'by [
some [copy attribute to fs thru fs (append output join attribute ";")]
]
copy attribute to end (append output attribute)]
]
parse [Customer is defined by First Name / Last Name / Email] definition-rule
probe output