WBR-tag invoegen
Nu passen die woorden niet altijd netjes op 1 regel. Ze moeten dan afbreken.
Met CSS's "word-wrap" kan je wel heel wat voor elkaar krijgen, maar dan breekt het soms verkeerd af.
Bijvoorbeeld als werkplaatsha-ndboek.
Dat wil ik niet.
Ik heb nu deze PHP-functie:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
function hyphen($string == '')
{
$string = str_replace("Werkplaatshandboek", "Werkplaats<wbr>handboek", $string);
$string = str_replace("Reclamemateriaal", "Reclame<wbr>materiaal", $string);
return $string;
}
?>
function hyphen($string == '')
{
$string = str_replace("Werkplaatshandboek", "Werkplaats<wbr>handboek", $string);
$string = str_replace("Reclamemateriaal", "Reclame<wbr>materiaal", $string);
return $string;
}
?>
Omdat het een zachte hyphen toegevoegd.
­ werkt niet zo goed in alle browsers als <wbr> wat staat voor word-break.
Maar dit is natuurlijk geen doen zo. Nu heb ik als voorbeeld nog maar 2 woorden, maar is dit makkelijk (en niet te veeleisend van de server) beter te doen?
Ik weet dat er in het Nederlands wel regels voor zijn, maar die zijn eigenlijk onmogelijk te implenteren.
Iemand een beter idee?
PS: ik heb al gezocht op hyphen php function etc, maar daar kwam niets zinnigs uit.
Toevoeging op 05/01/2013 11:28:09:
Niemand?
Maar ik vind het een interessant probleem, waar ik me heel vroeger in verdiept heb. Na wat zoeken vond ik het oude programma uit december 1992. Het was geschreven in C, dus niet bruikbaar voor dit doel. Maar ik vond het leuk om het om te werken naar PHP. Hier is het.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<?php
/**
* string breekaf(string)
* breekt een string af in lettergrepen volgens Nederlandse regels.
* Een Nederlandse lettergreep bestaat uit drie delen waarvan de eerste
* en de laatste mogen ontbreken:
* 1: een medeklinkergroep (kan lege string zijn)
* 2: een klinkergroep
* 3: een medeklinkergroep (kan lege string zijn)
* Copyright Ivo Breeden 1992, 2013
* Mutatie: 2013-01-06
* Betere resultaten worden verkregen door de string van achter naar
* voor te interpreteren. Dan volgt een betere beslissing of een
* medeklinkergroep een beginmedeklinkergroep is of een
* eindmedeklinkergroep.
*/
function breekaf($inwoord) {
// De lettergroepen zijn achterstevoren.
// een Nederlandse lettergreep kan maar met bepaalde medeklinkergroepen beginnen
$REbeginmkl = 'rhcs|hcs|rps|rts|ls|ms|lk|rf|uq|rk|nk|wk|rg|rb|rp|lp|ps|lv|rv|ns|lc|wz|hc|rw|ht|rd|ts|rt|wt|b|d|g|h|c|f|p|j|v|w|x|z|t|s|k|l|m|r|n';
// een Nederlandse lettergreep kan maar bepaalde klinkergroepen bevatten
$REklinker = 'wuee|iaa|wuo|ieo|ioo|swu|wua|ji|uu|ei|ue|ee|ie|aa|eo|ua|iu|uo|wu|oo|a|i|e|y|u|o';
// een Nederlandse lettergreep kan maar met bepaalde medeklinkergroepen eindigen
$REeindmkl = 'tsgr|tsfr|tsr|str|twr|tsn|thc|tsd|tsg|tbm|sgn|hcs|td|tl|gr|sm|st|tm|sl|tb|tg|dg|sk|dl|kl|fl|ts|sr|tp|dn|kr|tr|sp|hc|gn|dr|kn|tn|sn|f|x|d|t|b|s|g|p|r|n|m|k|l';
$inwoord = strrev($inwoord); // draai de input string om
$lucifers = array(); //matches zouden de Britten zeggen
$uitwoord = ''; //resultaat
$teststring = ''; //om te controleren of $inwoord heel gebleven is
// preg_match ook achterstevoren
$status = preg_match_all("/($REeindmkl)?($REklinker)($REbeginmkl)?/iu",
$inwoord,
$lucifers);
if ($status == 0) { //geen match of false
$uitwoord = $inwoord; //niet af te breken
} else { //match gevonden
$eerstekeer = true;
foreach ($lucifers[0] as $tmp) {
if ($eerstekeer) {
$uitwoord = $tmp;
$teststring = $tmp;
$eerstekeer = false;
} else {
$uitwoord .= '>rbw<'. $tmp; //nog steeds achterstevoren
$teststring .= $tmp;
}
}
}
//Als niet alles is herkend, geef dan het oorspronkelijke woord
if ($teststring != $inwoord) {
$uitwoord = $inwoord;
}
return strrev($uitwoord);
}
echo breekaf('werkplaatshandleiding') . "\n";
echo breekaf('Werkplaatshandboek') . "\n";
echo breekaf('Reclamemateriaal') . "\n";
echo breekaf('Onderdelencatalogus'). "\n";
echo breekaf('buitenboordmotor') . "\n";
echo breekaf('kilometerteller') . "\n";
echo breekaf('onderhoud') . "\n";
echo breekaf('A.N.W.B.') . "\n";
?>
Output:
werk<wbr>plaats<wbr>hand<wbr>lei<wbr>ding
Werk<wbr>plaats<wbr>hand<wbr>boek
Re<wbr>cla<wbr>me<wbr>ma<wbr>te<wbr>ri<wbr>aal
On<wbr>der<wbr>de<wbr>len<wbr>ca<wbr>ta<wbr>lo<wbr>gus
bui<wbr>ten<wbr>boord<wbr>mo<wbr>tor
ki<wbr>lo<wbr>me<wbr>ter<wbr>tel<wbr>ler
on<wbr>der<wbr>houd
A.N.W.B.
/**
* string breekaf(string)
* breekt een string af in lettergrepen volgens Nederlandse regels.
* Een Nederlandse lettergreep bestaat uit drie delen waarvan de eerste
* en de laatste mogen ontbreken:
* 1: een medeklinkergroep (kan lege string zijn)
* 2: een klinkergroep
* 3: een medeklinkergroep (kan lege string zijn)
* Copyright Ivo Breeden 1992, 2013
* Mutatie: 2013-01-06
* Betere resultaten worden verkregen door de string van achter naar
* voor te interpreteren. Dan volgt een betere beslissing of een
* medeklinkergroep een beginmedeklinkergroep is of een
* eindmedeklinkergroep.
*/
function breekaf($inwoord) {
// De lettergroepen zijn achterstevoren.
// een Nederlandse lettergreep kan maar met bepaalde medeklinkergroepen beginnen
$REbeginmkl = 'rhcs|hcs|rps|rts|ls|ms|lk|rf|uq|rk|nk|wk|rg|rb|rp|lp|ps|lv|rv|ns|lc|wz|hc|rw|ht|rd|ts|rt|wt|b|d|g|h|c|f|p|j|v|w|x|z|t|s|k|l|m|r|n';
// een Nederlandse lettergreep kan maar bepaalde klinkergroepen bevatten
$REklinker = 'wuee|iaa|wuo|ieo|ioo|swu|wua|ji|uu|ei|ue|ee|ie|aa|eo|ua|iu|uo|wu|oo|a|i|e|y|u|o';
// een Nederlandse lettergreep kan maar met bepaalde medeklinkergroepen eindigen
$REeindmkl = 'tsgr|tsfr|tsr|str|twr|tsn|thc|tsd|tsg|tbm|sgn|hcs|td|tl|gr|sm|st|tm|sl|tb|tg|dg|sk|dl|kl|fl|ts|sr|tp|dn|kr|tr|sp|hc|gn|dr|kn|tn|sn|f|x|d|t|b|s|g|p|r|n|m|k|l';
$inwoord = strrev($inwoord); // draai de input string om
$lucifers = array(); //matches zouden de Britten zeggen
$uitwoord = ''; //resultaat
$teststring = ''; //om te controleren of $inwoord heel gebleven is
// preg_match ook achterstevoren
$status = preg_match_all("/($REeindmkl)?($REklinker)($REbeginmkl)?/iu",
$inwoord,
$lucifers);
if ($status == 0) { //geen match of false
$uitwoord = $inwoord; //niet af te breken
} else { //match gevonden
$eerstekeer = true;
foreach ($lucifers[0] as $tmp) {
if ($eerstekeer) {
$uitwoord = $tmp;
$teststring = $tmp;
$eerstekeer = false;
} else {
$uitwoord .= '>rbw<'. $tmp; //nog steeds achterstevoren
$teststring .= $tmp;
}
}
}
//Als niet alles is herkend, geef dan het oorspronkelijke woord
if ($teststring != $inwoord) {
$uitwoord = $inwoord;
}
return strrev($uitwoord);
}
echo breekaf('werkplaatshandleiding') . "\n";
echo breekaf('Werkplaatshandboek') . "\n";
echo breekaf('Reclamemateriaal') . "\n";
echo breekaf('Onderdelencatalogus'). "\n";
echo breekaf('buitenboordmotor') . "\n";
echo breekaf('kilometerteller') . "\n";
echo breekaf('onderhoud') . "\n";
echo breekaf('A.N.W.B.') . "\n";
?>
Output:
werk<wbr>plaats<wbr>hand<wbr>lei<wbr>ding
Werk<wbr>plaats<wbr>hand<wbr>boek
Re<wbr>cla<wbr>me<wbr>ma<wbr>te<wbr>ri<wbr>aal
On<wbr>der<wbr>de<wbr>len<wbr>ca<wbr>ta<wbr>lo<wbr>gus
bui<wbr>ten<wbr>boord<wbr>mo<wbr>tor
ki<wbr>lo<wbr>me<wbr>ter<wbr>tel<wbr>ler
on<wbr>der<wbr>houd
A.N.W.B.
Deze afbreekroutine is verre van volmaakt. Dat blijkt al uit het afbreken van "Reclamemateriaal". Maar misschien heb je er wat aan, en misschien kun je het verbeteren.
Toevoeging op 06/01/2013 14:58:06:
Ik heb de source net vervangen. Het bleek een enorme verbetering te zijn om de woorden achterstevoren (strrev()) te analyseren. De source wordt er niet duidelijker van maar het resultaat gaat er erg op vooruit. Ik denk dat de afbreekroutine nu meer dan 90% goed resultaat geeft.
Ik hoop dat je er zo wat mee kunt.
Gewijzigd op 06/01/2013 14:55:10 door Ivo Breeden