Skip to content

Commit

Permalink
Merge 79ea88e into 3bf2c11
Browse files Browse the repository at this point in the history
  • Loading branch information
wyrfel committed Nov 6, 2019
2 parents 3bf2c11 + 79ea88e commit a71591f
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 5 deletions.
2 changes: 2 additions & 0 deletions src/Language/English.php
Expand Up @@ -45,6 +45,8 @@ class English implements LanguageInterface
'rev' => 'Rev.',
'sir' => 'Sir',
'prof' => 'Prof.',
'his honour' => 'His Honour',
'her honour' => 'Her Honour'
];

const LASTNAME_PREFIXES = [
Expand Down
57 changes: 52 additions & 5 deletions src/Mapper/SalutationMapper.php
Expand Up @@ -28,20 +28,67 @@ public function map(array $parts): array
$max = ($this->maxIndex > 0) ? $this->maxIndex : floor(count($parts) / 2);

for ($k = 0; $k < $max; $k++) {
$part = $parts[$k];

if ($part instanceof AbstractPart) {
if ($parts[$k] instanceof AbstractPart) {
break;
}

if ($this->isSalutation($part)) {
$parts[$k] = new Salutation($part, $this->salutations[$this->getKey($part)]);
$parts = $this->substituteWithSalutation($parts, $k);
}

return $parts;
}

/**
* We pass the full parts array and the current position to allow
* not only single-word matches but also combined matches with
* subsequent words (parts).
*
* @param array $parts
* @param int $start
* @return array
*/
protected function substituteWithSalutation(array $parts, int $start): array
{
if ($this->isSalutation($parts[$start])) {
$parts[$start] = new Salutation($parts[$start], $this->salutations[$this->getKey($parts[$start])]);
return $parts;
}

foreach ($this->salutations as $key => $salutation) {
$keys = explode(' ', $key);
$length = count($keys);

$subset = array_slice($parts, $start, $length);

if ($this->isMatchingSubset($keys, $subset)) {
array_splice($parts, $start, $length, [new Salutation(implode(' ', $subset), $salutation)]);
return $parts;
}
}

return $parts;
}

/**
* check if the given subset matches the given keys entry by entry,
* which means word by word, except that we first need to key-ify
* the subset words
*
* @param array $keys
* @param array $subset
* @return bool
*/
private function isMatchingSubset(array $keys, array $subset): bool
{
for ($i = 0; $i < count($subset); $i++) {
if ($this->getKey($subset[$i]) !== $keys[$i]) {
return false;
}
}

return true;
}

/**
* check if the given word is a viable salutation
*
Expand Down
7 changes: 7 additions & 0 deletions tests/ParserTest.php
Expand Up @@ -520,6 +520,13 @@ public function provider()
'lastname' => 'Du',
'firstname' => 'Yumeng',
]
],
[
'Her Honour Mrs Judy',
[
'lastname' => 'Judy',
'salutation' => 'Her Honour Mrs.'
]
]
];
}
Expand Down

0 comments on commit a71591f

Please sign in to comment.