Le funzioni personalizzate di FileMaker: questione di stile

Nell'articolo di oggi cercheremo di rispondere a due domande:

  1. dato un generico campo di testo, come possiamo isolare solamente le parole formattate con un determinato stile ?
  2. esiste la possibilità di creare più liste valori con le parole di un solo campo ?

Già nel 2007 scrissi un'apposita funzione personalizzata: GetStyledWords ( text ; style ). Quella che presento oggi, WordsWithStyle ( text ; style ), costituisce una sua evoluzione e miglioramento.

1. Individuare le parole in stile 

Per trovare in un campo testo le parole in stile, potremmo utilizzare la funzione nativa di FileMaker: GetAsSVG ( text ). Se in un campo text c'è scritto:

prova

GetAsSVG ( text ) restituisce:

<StyleList>
<Style#0>"font-weight: bold;", Begin: 1, End: 5</Style>
</StyleList>
<Data>
<SPAN STYLE="0">prova</SPAN>
</Data>

Come si può vedere, il primo Style della StyleList contiene la parola "bold", il termine inglese per "grassetto". Non solo: contiene anche la posizione d'inizio e di fine della parola stessa. Se il campo contenesse anche altre parole in grassetto una dietro l'altra, ad esempio

prova d'autore

GetAsSVG ( text ) restituirebbe

<StyleList>
<Style#0>"font-weight: bold;", Begin: 1, End: 14</Style>
</StyleList>
<Data>
<SPAN STYLE="0">prova d'autore</SPAN>
</Data>

Quindi, sempre un unico stile. Se invece il campo contenesse:

prova d'autore

GetAsSVG ( text ) restituirebbe:

<StyleList>
<Style#0>"font-weight: bold;", Begin: 1, End: 5</Style>
<Style#1>"font-style:italic;", Begin: 6, End: 8</Style>
<Style#2>"font-weight: bold;", Begin: 9, End: 14</Style>
</StyleList>
<Data>
<SPAN STYLE="0">prova</SPAN>
<SPAN STYLE="1"> d'</SPAN>
<SPAN STYLE="2">autore</SPAN>
</Data>

Tre style, ognuno con il suo nome e la posizione di inizio e fine. Tutto semplice, quindi? Purtroppo no. Principalmente per tre motivi:

  •  l'SVG di un testo "plain" (termine inglese per "normale") non contiene la parola "plain" ma semplicemente la stringa vuota ( "" );
  • alcuni stili di FileMaker non hanno equivalente in SVG ("parola sottolineata" e "doppia sottolineatura" sono semplicemente definiti come "sottolineato");
  • alcuni stili di FileMaker hanno un nome diverso in SVG (ad esempio "StrikeThrough" in SVG è "line-through").

Nella definizione della funzione personalizzata dovremo quindi operare alcune sostituzioni, oltre ad un parsing dell'SVG.

WordsWithStyle ( text ; style )

/*
WordsWithStyle ( text ; style ) Custom Function
Autore: Daniele Raybaudi
Parametri:
text: qualsiasi testo o campo di testo
style: lo stile ricercato nelle parole di text
Restituisce in formato lista tutte le parole del "text" in stile "style"
*/
Let ([
$cfWordsWithStyle = $cfWordsWithStyle + 1 ;
SVG = GetAsSVG ( text ) ;
SGVstyle = If ( IsEmpty ( style ) or style = "plain" ; "\"\"" ; Choose ( Ceiling ( Lg ( Evaluate ( style ) ) ) ;"thr" ;"small" ;"top" ;"bot" ;"upper" ;"lower" ;"capit" ;"" ;"bold" ;"italic" ;"under" ;"" ;"#F" ;" -2" ;" 2p" ) ) ;
parseSVG = MiddleValues ( SVG ; 2 ; PatternCount ( SVG ; "Style#" ) ) ;
line = GetValue ( parseSVG ; $cfWordsWithStyle ) ;
pos1 = Middle ( line ; Position ( line ; "," ; 1 ; 1 ) + 1 ; Position ( line ; "," ; 1 ; 2 ) - Position ( line ; "," ; 1 ; 1 ) - 1 ) ;
pos2 = Middle ( line ; Position ( line ; "," ; 1 ; 2 ) + 1 ; Position ( line ; "<" ; 1 ; 2 ) - Position ( line ; "," ; 1 ; 2 ) - 1 ) ;
string = Middle ( text ; pos1 ; pos2 - pos1 + 1 ) ;
adjString = Substitute ( TrimAll ( Substitute ( string ; ¶ ; " " ) ; 1 ; 1 ) ; " " ; ¶ )
];
Case(
$cfWordsWithStyle < ValueCount ( parseSVG ) ;
Case(
PatternCount ( line ; SGVstyle ) ; List ( adjString ; WordsWithStyle ( text ; style ) ) ;
WordsWithStyle ( text ; style )
);
Let ( $cfWordsWithStyle = "" ; If ( PatternCount ( line ; SGVstyle ) ; adjString ) )
)
)

Commento per riga della funzione personalizzata

Dichiariamo alcune variabili [(
$cfWordsWithStyle: variabile locale che si autoincrementa di 1 ad ogni recursione
SVG: variabile di LET che contiene il risultato della funzione nativa GetAsSVG ( text )
SGVstyle: variabile di LET che opera alcune sostituzioni per superare i punti a) e c) precedentemente descritti ( vedi precisazione seguente )
parseSVG: variabile di LET che contiene una lista valori dei soli "style" dell'SVG
line: variabile di LET che contiene, ad ogni recursione, un solo valore della precedente lista valori
pos1: variabile di LET che contiene la posizione iniziale della parola
pos2: variabile di LET che contiene la posizione finale della parola
string: variabile di LET che contiene la parola
adjString: variabile di LET che, se la parola fosse composta da più parole, le scriverebbe come lista valori
];
Finchè la variabile locale $cfWordsWithStyle risulta minore del numero degli "style" dell'SVG ;
Se lo "style" contiene SGVstyle ; scrivi come lista adjstring e ripeti dall'inizio ;
Se invece non la contiene , non scrivere niente e ripeti dall'inizio ;
poi azzera la variabile locale $cfWordsWithStyle e, se lo "style" contiene SGVstyle, scrivi come lista adjstring ed ESCI
)

A proposito del parametro SVGstyle

Nel mio ultimo articolo su Guru in Pillole avevo mostrato uno specchietto di equivalenza tra gli stili di FileMaker e alcuni numeri. Spesso però, gli stili dell'SGV hanno nomi differenti: per semplificare il più possibile il calcolo di questa variabile, abbiamo usato la funzione Lg( ) in abbinamento con le funzioni Ceiling( ) e Choose( ). Notiamo infatti che quasi tutti quei numeri sono potenze di 2.

Ricordando che

2^0 = 1 = StrikeThrough
2^1 = 2 = SmallCaps
2^2 = 4 = SuperScript
2^3 = 8 = SubScript
2^4 = 16 = UpperCase
2^5 = 32 = LowerCase
2^5 + 2^4 = 48 = TitleCase
2^6 = 64 = WordUnderline
2^7 = 128 = DoubleUnderline
2^8 = 256 = Bold
2^9 = 512 = Italic
2^10 = 1024 = Underline
2^11 = 2048
2^12 = 4096 = HighlightYellow
2^13 = 8192 = Condense
2^14 = 16384 = Extend

poichè il logaritmo è l'operazione inversa della potenza, avremo:

lg 1 = 0
lg 2 = 1
lg 4 = 2
...
lg 8192 = 13
lg 16384 = 14

2. Creare liste valori

Esiste la possibilità di creare più liste valori con le parole di un solo campo? La risposta è sì, utilizzando proprio questa funzione personalizzata. [download id="1025"] per scaricare un esempio .fp7, da convertire eventualmente in .fmp12.

E tu come hai risolto le tue questioni di stile? Parlane con noi nel Guru Corner!




Nessuna domanda trovata.

Daniele Raybaudi

Cerca
Prendi la corsia preferenziale e risolvi i tuoi problemi di sviluppo FileMaker!

Risorse gratuite

Guru Corner

Altri articoli di Daniele Raybaudi

Ultimi articoli