Changes between Initial Version and Version 1 of Rules/ChargeRules


Ignore:
Timestamp:
2024-08-11T19:22:51+02:00 (18 months ago)
Author:
Famlam
Comment:

Initial version

Legend:

Unmodified
Added
Removed
Modified
  • Rules/ChargeRules

    v1 v1  
     1= Charge validation rules
     2
     3These rules provide validation for the keys `charge` and `charge:conditional`, following the syntax documented on [osmwiki:Key:charge].
     4
     5They check the syntax, but do not check whether the values makes sense (e.g. fuel for €0.01 per m³), that remains up to the user.
     6
     7== Bugs / enhancements?
     8Please feel free to [osmwww:message/new/Famlam message] in case you find a bug.
     9You can also edit this page if you're familiar with the syntax :)
     10
     11=== Structure and maintenance
     12I tried to keep the rules as simple as possible, both to maintain and for the user. Hence it first validates some 'common' issues with more specific messages, before validating the full syntax with an unspecific message. Usually the regexes are as similar as possible for both validated keys, and in case there are differences, these are indicated in comments above the rules.
     13
     14The asserts only work when the class selectors aren't present, so to use those you have to temporarily remove the class selector. Note that the asserts only serve to check the syntax, they don't always make sense. Be aware that the negative asserts also require the class selector to be (temporarily) removed, they just don't give any error when they remain enabled, hence they're not commented out by default.
     15
     16For the conditional tag it usually only validates the part up to the first `@` as the condition after the `@` may contain any character (especially in fallback rules), thus making it difficult to ensure (with mapcss) that the condition is truly over.
     17
     18== Rules source code == #SourceCode
     19{{{
     20#!rule
     21meta {
     22    title: "Charge validation rules";
     23    version: "1.[[revision]]_[[date]]";
     24    description: "Rules to validate the charge and charge:conditional keys.";
     25    author: "Famlam";
     26    min-josm-version: "6534";
     27    link: "https://josm.openstreetmap.de/wiki/Rules/ChargeRules";
     28}
     29
     30
     31
     32/* Currency symbols (e.g. €) instead of codes (EUR) */
     33*[charge:conditional=~/\p{Sc}/],
     34*[charge=~/\p{Sc}/] {
     35  throwWarning: tr("Expected 3-character currency code in {0}, found {1} instead", "{0.key}", get(regexp_match("^.*(\\p{Sc}).*$", tag("{0.key}")), 1));
     36  group: tr("Invalid value of charge");
     37  assertMatch: "node charge=€12";
     38  assertMatch: "node charge:conditional=\"0.22 $/liter @ (Mo-Fr)\"";
     39  assertNoMatch: "node charge=\"0.223 USD/m³\"";
     40  set .hasSimpleChargeFix;
     41}
     42
     43/* Currency code before the value instead of after */
     44*[charge:conditional=~/^[A-Z]{3} ?[0-9]/]!.hasSimpleChargeFix,
     45*[charge=~/^[A-Z]{3} ?[0-9]/]!.hasSimpleChargeFix {
     46  throwWarning: tr("The value should be before the currency code {0} in {1}", substring(tag("{0.key}"), 0, 3), "{0.key}");
     47  group: tr("Invalid value of charge");
     48  /* For the positive assertions, first remove !.hasSimpleChargeFix from the rule; don't forget to restore */
     49  /*
     50  assertMatch: "node charge=EUR12.45";
     51  assertMatch: "node charge=\"EUR 12\"";
     52  */
     53  assertNoMatch: "node charge=\"0.223 USD/m³\"";
     54  set .hasSimpleChargeFix;
     55}
     56
     57/* Missing mandatory space between value and currency code */
     58*[charge:conditional=~/^[0-9]+(?:\.[0-9]+)?[A-Z]{3}/]!.hasSimpleChargeFix,
     59*[charge=~/^[0-9]+(?:\.[0-9]+)?[A-Z]{3}/]!.hasSimpleChargeFix {
     60  throwWarning: tr("The value and the currency symbol in {0} should be separated by a space", "{0.key}");
     61  group: tr("Invalid value of charge");
     62  /* For the positive assertions, first remove !.hasSimpleChargeFix from the rule; don't forget to restore */
     63  /*
     64  assertMatch: "node charge=12EUR";
     65  */
     66  assertNoMatch: "node charge=\"12 EUR\"";
     67  assertNoMatch: "node charge=\"0.223 USD/m³\"";
     68  set .hasSimpleChargeFix;
     69}
     70
     71/* No currency, just a value */
     72/* Regexes differ, charge:conditional has "( ?@| ?\/)", charge has "($| ?\/)" at the end */
     73*[charge:conditional=~/^[0-9]+(?:\.[0-9]+)?( ?@| ?\/)/]!.hasSimpleChargeFix,
     74*[charge=~/^[0-9]+(?:\.[0-9]+)?($| ?\/)/][charge!=0]!.hasSimpleChargeFix {
     75  throwWarning: tr("Currency not specified in {0}", "{0.key}");
     76  group: tr("Invalid value of charge");
     77  /* For the positive assertions, first remove !.hasSimpleChargeFix from the rule; don't forget to restore */
     78  /*
     79  assertMatch: "node charge=12";
     80  assertMatch: "node charge:conditional=\"12.45/liter @ (Mo-Fr)\"";
     81  */
     82  assertNoMatch: "node charge=\"0.223 USD/m³\"";
     83  assertNoMatch: "node charge=0";
     84  set .hasSimpleChargeFix;
     85}
     86
     87/* yes/no instead of the actual fee */
     88/* Regexes differ, charge:conditional has " ?@", charge has "$" at the end */
     89*[charge:conditional][charge:conditional=~/^(yes|no) ?@/],
     90*[charge][charge=~/^(yes|no)$/] {
     91  throwWarning: tr("Key {0} should contain the amount charged", "{0.key}");
     92  group: tr("Invalid value of charge");
     93  suggestAlternative: "fee={0.value}";
     94  suggestAlternative: "toll={0.value}";
     95  suggestAlternative: "fee:conditional={0.value} @ ...";
     96  suggestAlternative: "toll:conditional={0.value} @ ...";
     97  set .hasSimpleChargeFix;
     98}
     99
     100/* Comma as decimal separator */
     101*[charge:conditional=~/(^|\/ ?)[0-9]+,[0-9]/]!.hasSimpleChargeFix,
     102*[charge=~/(^|\/ ?)[0-9]+,[0-9]/]!.hasSimpleChargeFix {
     103  throwWarning: tr("unusual value of {0}: use . instead of , as decimal separator", "{0.key}");
     104  group: tr("Invalid value of charge");
     105  /* For the positive assertions, first remove !.hasSimpleChargeFix from the rule; don't forget to restore */
     106  /*
     107  assertMatch: "node charge=\"0,223 USD/30.4 m³\"";
     108  assertMatch: "node charge=\"0.223 USD/30,4 m³\"";
     109  */
     110  assertNoMatch: "node charge=\"0.223 USD/30.4 m³\"";
     111  set .hasSimpleChargeFix;
     112}
     113
     114/* Currency (likely) written out or wrong abbreviation used */
     115*[charge:conditional=~/^([0-9]+(?:\.[0-9]+)? ?[A-Za-z _-]+|[A-Za-z _-]+ ?[0-9]+(?:\.[0-9]+)?)/][charge:conditional!~/^[0-9]+(?:\.[0-9]+)? ?[A-Z]{3}/]!.hasSimpleChargeFix,
     116*[charge=~/^([0-9]+(?:\.[0-9]+)? ?[A-Za-z _-]+|[A-Za-z _-]+ ?[0-9]+(?:\.[0-9]+)?)/][charge!~/^[0-9]+(?:\.[0-9]+)? ?[A-Z]{3}/]!.hasSimpleChargeFix {
     117  throwWarning: tr("Invalid currency code in {0}, should be a 3-letter (uppercase) code after the value", "{0.key}");
     118  group: tr("Invalid value of charge");
     119  /* For the positive assertions, first remove !.hasSimpleChargeFix from the rule; don't forget to restore */
     120  /*
     121  assertMatch: "node charge=\"12 euro\"";
     122  assertMatch: "node charge=\"12 US dollar\"";
     123  assertMatch: "node charge=\"E12.95\"";
     124  assertMatch: "node charge=\"12.95E\"";
     125  assertMatch: "node charge=\"usdollar 12.95\"";
     126  assertMatch: "node charge=\"US Dollar 12.95\"";
     127  assertMatch: "node charge:conditional=\"12.45E @ (Mo-Fr)\"";
     128  */
     129  assertNoMatch: "node charge=\"0.223 USD/m³\"";
     130  assertNoMatch: "node charge=\"0.223USD\"";
     131  assertNoMatch: "node charge:conditional=\"0.223 USD @ (Mo-Fr)\"";
     132  set .hasSimpleChargeFix;
     133}
     134
     135/* Abbreviated time unit */
     136/* Regexes differ, charge:conditional has "^[^@]+" and " ?@.", charge has "" and "$" at the start and end respectively */
     137*[charge:conditional=~/^[^@]+\/ ?(?:[0-9]+(?:\.[0-9]+)? ?)?(min|s|h|d|w) ?@./]!.hasSimpleChargeFix,
     138*[charge=~/\/ ?(?:[0-9]+(?:\.[0-9]+)? ?)?(min|s|h|d|w)$/]!.hasSimpleChargeFix {
     139  throwWarning: tr("Abbreviated time unit in {0}", "{0.key}");
     140  group: tr("Invalid value of charge");
     141  /* For the positive assertions, first remove !.hasSimpleChargeFix from the rule; don't forget to restore */
     142  /*
     143  assertMatch: "node charge=\"12 EUR/h\"";
     144  assertMatch: "node charge:conditional=\"12 EUR/h @ Sa\"";
     145  assertMatch: "node charge=\"12 EUR/0.5 h\"";
     146  */
     147  assertNoMatch: "node charge=\"0.22 USD/liter/hour\"";
     148  assertNoMatch: "node charge=\"12.223 YEN/12.4 m³/30.1 minutes\"";
     149  set .hasSimpleChargeFix;
     150}
     151
     152/* Missing space between value and unit in the optional unit parts */
     153/* Regexes differ, charge:conditional has "^[^@]+" and "( ?@| ?\/).", charge has "" and "($| ?\/)" at the start and end respectively */
     154*[charge:conditional=~/^[^@]+\/ ?[0-9]+(?:\.[0-9]+)?[a-zA-Z³]+( ?@| ?\/)./]!.hasSimpleChargeFix,
     155*[charge=~/\/ ?[0-9]+(?:\.[0-9]+)?[a-zA-Z³]+($| ?\/)/]!.hasSimpleChargeFix {
     156  throwWarning: tr("No space between value and unit in {0}", "{0.key}");
     157  group: tr("Invalid value of charge");
     158  /* For the positive assertions, first remove !.hasSimpleChargeFix from the rule; don't forget to restore */
     159  /*
     160  assertMatch: "node charge=\"12 EUR/0.5hour\"";
     161  assertMatch: "node charge=\"12 EUR/3kWh/0.5 hour\"";
     162  assertMatch: "node charge=\"12 EUR/3kWh/0.5hour\"";
     163  assertMatch: "node charge=\"12 EUR/3 kWh/2hours\"";
     164  assertMatch: "node charge=\"12 EUR/3kWh/hour\"";
     165  assertMatch: "node charge=\"12 EUR/kWh/0.5hour\"";
     166  assertMatch: "node charge:conditional=\"12.5 EUR/0.5hour @ Sa\"";
     167  */
     168  assertNoMatch: "node charge=\"0.22 USD/liter/hour\"";
     169  assertNoMatch: "node charge=\"12.223 YEN/12.4 m³/30.1 minutes\"";
     170  set .hasSimpleChargeFix;
     171}
     172
     173/* For charge:conditional, only validate the first condition. The @-condition may contain any character (esp. in fallback conditions).*/
     174/* The regexes are the same until the "(?:; ?(?!$)|$))+$" vs " ?@)."-part at the end */
     175*[charge:conditional][charge:conditional!~/^(?:[0-9]+(?:\.[0-9]+)? [A-Z]{3}(?: ?\/ ?(?:[0-9]+(?:\.[0-9]+)? )?[a-zA-Z³]+)?(?: ?\/ ?(?:[0-9]+(?:\.[0-9]+)? )?[a-z]{3,})? ?@)./]!.hasSimpleChargeFix,
     176*[charge][charge!=0][charge!~/^(?:[0-9]+(?:\.[0-9]+)? [A-Z]{3}(?: ?\/ ?(?:[0-9]+(?:\.[0-9]+)? )?[a-zA-Z³]+)?(?: ?\/ ?(?:[0-9]+(?:\.[0-9]+)? )?[a-z]{3,})?(?:; ?(?!$)|$))+$/]!.hasSimpleChargeFix {
     177  throwWarning: tr("The charge in {0} should be structured as <(decimal) number><space><(uppercase) three letter currency code>[/optional unit][/optional time unit]", "{0.key}");
     178  group: tr("Invalid value of charge");
     179  /* For the positive assertions, first remove !.hasSimpleChargeFix from the rule; don't forget to restore */
     180  /*
     181  assertMatch: "node charge=€12";
     182  assertMatch: "node charge=\"0.22 $/liter\"";
     183  assertMatch: "node charge=12.22";
     184  assertMatch: "node charge=\"12 EURO\"";
     185  assertMatch: "node charge=\"12 eur\"";
     186  assertMatch: "node charge=12EUR";
     187  assertMatch: "node charge=EUR12";
     188  assertMatch: "node charge:conditional=\"EUR12 @ (Fr-Su)\"";
     189  assertMatch: "node charge=\"12 EUR/5\"";
     190  assertMatch: "node charge=\"12 EUR;\"";
     191  */
     192  assertNoMatch: "node charge=0"; /* Zero is zero regardless of the unit, ignore */
     193  assertNoMatch: "node charge=\"12 EUR\"";
     194  assertNoMatch: "node charge=\"12 EUR/person; 6 EUR/child\"";
     195  assertNoMatch: "node charge=\"0.223 USD/liter\"";
     196  assertNoMatch: "node charge=\"0.22 USD/liter/hour\"";
     197  assertNoMatch: "node charge=\"0.22 USD / liter / hour\"";
     198  assertNoMatch: "node charge=\"12.223 YEN/1 person/1 hour\"";
     199  assertNoMatch: "node charge=\"12.223 YEN/12.4 m³/30.1 minutes\"";
     200  assertNoMatch: "node charge:conditional=\"12.223 YEN/12.4 m³/30.1 minutes @ Fr-Su\"";
     201  assertNoMatch: "node charge=\"12.223 YEN/100 kWh/day\"";
     202}
     203}}}