emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/ebdb 6cc67a7 315/350: Add instructions for writing i18n


From: Eric Abrahamsen
Subject: [elpa] externals/ebdb 6cc67a7 315/350: Add instructions for writing i18n libraries to manual
Date: Mon, 14 Aug 2017 11:47:02 -0400 (EDT)

branch: externals/ebdb
commit 6cc67a79e0277e519fe6fa240761f0de5ae5e364
Author: Eric Abrahamsen <address@hidden>
Commit: Eric Abrahamsen <address@hidden>

    Add instructions for writing i18n libraries to manual
    
    * ebdb.org (Writing Internationalization Libraries): New section.
    * ebdb.info: etc
    * ebdb.texi: etc
---
 ebdb.info | 197 ++++++++++++++++++++++++++++++++++++++++++++++++--------------
 ebdb.org  |  93 +++++++++++++++++++++++++++++
 ebdb.texi | 118 +++++++++++++++++++++++++++++++++++++
 3 files changed, 363 insertions(+), 45 deletions(-)

diff --git a/ebdb.info b/ebdb.info
index b9af231..5b8c5f8 100644
--- a/ebdb.info
+++ b/ebdb.info
@@ -103,6 +103,10 @@ Searching
 
 
 
+Internationalization
+
+* Writing Internationalization Libraries::
+
 
 
 
@@ -1138,6 +1142,108 @@ can (depending on country libraries’ behavior) increase 
database load
 times, though it should not significantly affect search or display
 performance.
 
+* Menu:
+
+* Writing Internationalization Libraries::
+
+
+File: ebdb.info,  Node: Writing Internationalization Libraries,  Up: 
Internationalization
+
+9.1 Writing Internationalization Libraries
+==========================================
+
+Writing new internationalization libraries involves using generic
+functions.  *note Generic Functions: (elisp)Generic%20Functions.  It
+will also require a bit of familiarity with EBDB’s internals.
+
+   Internationalization affects three different field types: addresses,
+phone numbers, and names.  It works by providing “i18n” versions of
+common methods for those three fields:
+
+Regular method      Internationalized method
+-----------------------------------------------
+ebdb-read           ebdb-read-i18n
+ebdb-parse          ebdb-parse-i18n
+ebdb-string         ebdb-string-i18n
+ebdb-init-field     ebdb-init-field-i18n
+ebdb-delete-field   ebdb-delete-field-i18n
+
+   When the “ebdb-i18n” library is loaded and the left-column
+(“vanilla”) versions of field methods are called, EBDB first checks to
+see if a valid “internationalized” (right-column) method exists.  If it
+does, that method is used instead of the vanilla one.
+
+   What is a “valid internationalized method”?  That depends on the
+field type.  Each field type uses a different key or “spec” to determine
+the nationality or locality of the field instance.
+
+   • Address fields use a three-character symbol derived from the ISO
+     316601 alpha 3 (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3)
+     country codes.  These codes can be found in the variable
+     ‘ebdb-i18n-countries’.
+
+   • Phone fields use the phone number’s numerical country code as a
+     spec.  These codes can be found in the variable
+     ‘ebdb-i18n-phone-codes’.
+
+   • Name fields are keyed to the symbol representing the script used to
+     write them.  Specifically, the first character CHAR of the name is
+     tested in this way: (aref char-script-table CHAR), which returns a
+     symbol.
+
+   How are these “specs” used?  Each internationalized version of the
+above methods accepts the spec as an additional argument, which it is
+able to specialize on.  Every country-specific method should check the
+spec to see if it is relevant to that library.  If so, it handles the
+necessary behavior; if not, it passes by using ‘cl-call-next-method’.
+See the function signatures of each internationalized method to find how
+to handle the extra argument, called SPEC.
+
+   Here’s a concrete example:
+
+   Say we want to make sure all French phone numbers are represented by
+a string that looks like “+33 05 12 34 56 79”.  This is not how they are
+stored in the database, but this is how they should be represented to
+the user.  We need to override the ‘ebdb-string-i18n’ method for the
+phone field class.  This method takes two arguments – the field
+instance, and the country-code spec – and needs to specialize on both
+arguments.  The method signature will look like this:
+
+     (cl-defmethod ebdb-string-i18n ((phone ebdb-field-phone)
+                               (_cc (eql 33))))
+
+   See the manual on generic functions for details; suffice it to say
+that this method will only run when the first argument is an instance of
+the ‘ebdb-field-phone’ class (or a subclass), and the second argument is
+the number 33.
+
+   Now we know that this method will only run for French phone numbers,
+so we can format the number correctly:
+
+     (cl-defmethod ebdb-string-i18n ((phone ebdb-field-phone)
+                               (_cc (eql 33)))
+       (with-slots (area-code number extension) phone
+         (concat
+          "+33 "
+          (when area-code
+            (format "%02d" area-code))
+          (format "%s%s %s%s %s%s %s%s"
+            (split-string number "" t))
+          (when extension
+            (format "X%d" extension)))))
+
+   Again this only affects the display of numbers, not how they are
+stored in the database.
+
+   Note that, while phone numbers themselves are stored as strings (they
+do not represent a quantity, after all), the country and area codes are
+stored as numbers, precisely so that they can be specialized on using
+‘eql’.
+
+   See the signatures of the other internationalized methods for how to
+use them.  The symbol specs for country codes and script names can also
+be specialized on with the ‘eql’ specializer.
+
 
 File: ebdb.info,  Node: Diary Integration,  Next: Mail Aliases,  Prev: 
Internationalization,  Up: Top
 
@@ -1644,51 +1750,52 @@ Index
 
 Tag Table:
 Node: Top806
-Node: Getting Started2151
-Node: Migration from BBDB2773
-Node: Record Migration2948
-Node: Variables and Options3485
-Node: The EBDB Database3971
-Node: Creating Records7127
-Node: Record classes8174
-Node: Record names8440
-Node: Record Fields9115
-Node: Inserting new fields9359
-Node: Editing existing fields10155
-Node: Deleting records and fields10755
-Node: Field types11151
-Node: MUA Interaction12970
-Node: Loading MUA Code13494
-Node: Display and Updating14207
-Node: Pop-up Buffers14976
-Node: Auto-Updating Records15841
-Node: Noticing and Automatic Rules18226
-Node: Interactive Commands19569
-Node: EBDB and MUA summary buffers22058
-Node: Sender name display22544
-Node: Summary buffer marks23832
-Node: EBDB Buffers25027
-Node: Searching26220
-Node: Changing Search Behavior27930
-Node: The Basics of ebdb-mode29180
-Node: Marking32544
-Node: Exporting/Formatting32972
-Node: Completion33931
-Node: Snarfing35072
-Node: Internationalization36976
-Node: Diary Integration38402
-Node: Mail Aliases39268
-Node: vCard Support39977
-Node: Org Integration40476
-Node: Citing Records42050
-Node: Hacking EBDB42809
-Node: Field Classes45059
-Node: Init and Delete Methods47949
-Node: The Labeled Field Class49505
-Node: Actions50341
-Node: Custom Field Searching51006
-Node: Formatting in the EBDB Buffer52794
-Node: Index54793
+Node: Getting Started2217
+Node: Migration from BBDB2839
+Node: Record Migration3014
+Node: Variables and Options3551
+Node: The EBDB Database4037
+Node: Creating Records7193
+Node: Record classes8240
+Node: Record names8506
+Node: Record Fields9181
+Node: Inserting new fields9425
+Node: Editing existing fields10221
+Node: Deleting records and fields10821
+Node: Field types11217
+Node: MUA Interaction13036
+Node: Loading MUA Code13560
+Node: Display and Updating14273
+Node: Pop-up Buffers15042
+Node: Auto-Updating Records15907
+Node: Noticing and Automatic Rules18292
+Node: Interactive Commands19635
+Node: EBDB and MUA summary buffers22124
+Node: Sender name display22610
+Node: Summary buffer marks23898
+Node: EBDB Buffers25093
+Node: Searching26286
+Node: Changing Search Behavior27996
+Node: The Basics of ebdb-mode29246
+Node: Marking32610
+Node: Exporting/Formatting33038
+Node: Completion33997
+Node: Snarfing35138
+Node: Internationalization37042
+Node: Writing Internationalization Libraries38521
+Node: Diary Integration42809
+Node: Mail Aliases43675
+Node: vCard Support44384
+Node: Org Integration44883
+Node: Citing Records46457
+Node: Hacking EBDB47216
+Node: Field Classes49466
+Node: Init and Delete Methods52356
+Node: The Labeled Field Class53912
+Node: Actions54748
+Node: Custom Field Searching55413
+Node: Formatting in the EBDB Buffer57201
+Node: Index59200
 
 End Tag Table
 
diff --git a/ebdb.org b/ebdb.org
index ed40cec..e8850bc 100644
--- a/ebdb.org
+++ b/ebdb.org
@@ -864,6 +864,99 @@ parses and displays field values, and can also store extra 
information
 Loading this library can (depending on country libraries' behavior)
 increase database load times, though it should not significantly
 affect search or display performance.
+** Writing Internationalization Libraries
+Writing new internationalization libraries involves using generic
+functions. [[info:elisp#Generic%20Functions][Generic Functions]].  It will 
also require a bit of
+familiarity with EBDB's internals.
+
+Internationalization affects three different field types: addresses,
+phone numbers, and names.  It works by providing "i18n" versions of
+common methods for those three fields:
+
+| Regular method    | Internationalized method |
+|-------------------+--------------------------|
+| ebdb-read         | ebdb-read-i18n           |
+| ebdb-parse        | ebdb-parse-i18n          |
+| ebdb-string       | ebdb-string-i18n         |
+| ebdb-init-field   | ebdb-init-field-i18n     |
+| ebdb-delete-field | ebdb-delete-field-i18n   |
+
+When the "ebdb-i18n" library is loaded and the left-column ("vanilla")
+versions of field methods are called, EBDB first checks to see if a
+valid "internationalized" (right-column) method exists.  If it does,
+that method is used instead of the vanilla one.
+
+What is a "valid internationalized method"?  That depends on the field
+type.  Each field type uses a different key or "spec" to determine the
+nationality or locality of the field instance.
+
+- Address fields use a three-character symbol derived from the 
[[https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3][ISO
+  316601 alpha 3]] country codes.  These codes can be found in the
+  variable ~ebdb-i18n-countries~.
+- Phone fields use the phone number's numerical country code as a
+  spec.  These codes can be found in the variable
+  ~ebdb-i18n-phone-codes~.
+- Name fields are keyed to the symbol representing the script used to
+  write them. Specifically, the first character CHAR of the name is
+  tested in this way: =(aref char-script-table CHAR)=, which returns a
+  symbol.
+
+How are these "specs" used?  Each internationalized version of the
+above methods accepts the spec as an additional argument, which it is
+able to specialize on.  Every country-specific method should check the
+spec to see if it is relevant to that library. If so, it handles the
+necessary behavior; if not, it passes by using ~cl-call-next-method~.
+See the function signatures of each internationalized method to find
+how to handle the extra argument, called SPEC.
+
+Here's a concrete example:
+
+Say we want to make sure all French phone numbers are represented by a
+string that looks like "+33 05 12 34 56 79".  This is not how they are
+stored in the database, but this is how they should be represented to
+the user.  We need to override the ~ebdb-string-i18n~ method for the
+phone field class.  This method takes two arguments -- the field
+instance, and the country-code spec -- and needs to specialize on both
+arguments.  The method signature will look like this:
+
+#+BEGIN_SRC emacs-lisp
+  (cl-defmethod ebdb-string-i18n ((phone ebdb-field-phone)
+                                  (_cc (eql 33))))
+#+END_SRC
+
+See the manual on generic functions for details; suffice it to say
+that this method will only run when the first argument is an instance
+of the ~ebdb-field-phone~ class (or a subclass), and the second
+argument is the number 33.
+
+Now we know that this method will only run for French phone numbers,
+so we can format the number correctly:
+
+#+BEGIN_SRC emacs-lisp
+  (cl-defmethod ebdb-string-i18n ((phone ebdb-field-phone)
+                                  (_cc (eql 33)))
+    (with-slots (area-code number extension) phone
+      (concat
+       "+33 "
+       (when area-code
+         (format "%02d" area-code))
+       (format "%s%s %s%s %s%s %s%s"
+               (split-string number "" t))
+       (when extension
+         (format "X%d" extension)))))
+#+END_SRC
+
+Again this only affects the display of numbers, not how they are
+stored in the database.
+
+Note that, while phone numbers themselves are stored as strings (they
+do not represent a quantity, after all), the country and area codes
+are stored as numbers, precisely so that they can be specialized on
+using ~eql~.
+
+See the signatures of the other internationalized methods for how to
+use them.  The symbol specs for country codes and script names can
+also be specialized on with the ~eql~ specializer.
 * Diary Integration
 #+CINDEX: Diary integration
 Some EBDB fields hold dates or anniversaries (most notably the
diff --git a/ebdb.texi b/ebdb.texi
index 3c62352..02ebe4c 100644
--- a/ebdb.texi
+++ b/ebdb.texi
@@ -124,6 +124,10 @@ Searching
 
 
 
+Internationalization
+
+* Writing Internationalization Libraries::
+
 
 
 
@@ -1249,6 +1253,120 @@ Loading this library can (depending on country 
libraries' behavior)
 increase database load times, though it should not significantly
 affect search or display performance.
 
address@hidden
+* Writing Internationalization Libraries::
address@hidden menu
+
address@hidden Writing Internationalization Libraries
address@hidden Writing Internationalization Libraries
+
+Writing new internationalization libraries involves using generic
+functions. @ref{Generic%20Functions,Generic Functions,,elisp,}.  It will also 
require a bit of
+familiarity with EBDB's internals.
+
+Internationalization affects three different field types: addresses,
+phone numbers, and names.  It works by providing ``i18n'' versions of
+common methods for those three fields:
+
address@hidden {aaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaa}
address@hidden Regular method
address@hidden Internationalized method
address@hidden ebdb-read
address@hidden ebdb-read-i18n
address@hidden ebdb-parse
address@hidden ebdb-parse-i18n
address@hidden ebdb-string
address@hidden ebdb-string-i18n
address@hidden ebdb-init-field
address@hidden ebdb-init-field-i18n
address@hidden ebdb-delete-field
address@hidden ebdb-delete-field-i18n
address@hidden multitable
+
+When the ``ebdb-i18n'' library is loaded and the left-column (``vanilla'')
+versions of field methods are called, EBDB first checks to see if a
+valid ``internationalized'' (right-column) method exists.  If it does,
+that method is used instead of the vanilla one.
+
+What is a ``valid internationalized method''?  That depends on the field
+type.  Each field type uses a different key or ``spec'' to determine the
+nationality or locality of the field instance.
+
address@hidden
address@hidden
+Address fields use a three-character symbol derived from the 
@uref{https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3, ISO
+316601 alpha 3} country codes.  These codes can be found in the
+variable @code{ebdb-i18n-countries}.
+
address@hidden
+Phone fields use the phone number's numerical country code as a
+spec.  These codes can be found in the variable
address@hidden
+
address@hidden
+Name fields are keyed to the symbol representing the script used to
+write them. Specifically, the first character CHAR of the name is
+tested in this way: @verb{~(aref char-script-table CHAR)~}, which returns a
+symbol.
address@hidden itemize
+
+How are these ``specs'' used?  Each internationalized version of the
+above methods accepts the spec as an additional argument, which it is
+able to specialize on.  Every country-specific method should check the
+spec to see if it is relevant to that library. If so, it handles the
+necessary behavior; if not, it passes by using @code{cl-call-next-method}.
+See the function signatures of each internationalized method to find
+how to handle the extra argument, called SPEC.
+
+Here's a concrete example:
+
+Say we want to make sure all French phone numbers are represented by a
+string that looks like ``+33 05 12 34 56 79''.  This is not how they are
+stored in the database, but this is how they should be represented to
+the user.  We need to override the @code{ebdb-string-i18n} method for the
+phone field class.  This method takes two arguments -- the field
+instance, and the country-code spec -- and needs to specialize on both
+arguments.  The method signature will look like this:
+
address@hidden
+(cl-defmethod ebdb-string-i18n ((phone ebdb-field-phone)
+                               (_cc (eql 33))))
address@hidden lisp
+
+See the manual on generic functions for details; suffice it to say
+that this method will only run when the first argument is an instance
+of the @code{ebdb-field-phone} class (or a subclass), and the second
+argument is the number 33.
+
+Now we know that this method will only run for French phone numbers,
+so we can format the number correctly:
+
address@hidden
+(cl-defmethod ebdb-string-i18n ((phone ebdb-field-phone)
+                               (_cc (eql 33)))
+  (with-slots (area-code number extension) phone
+    (concat
+     "+33 "
+     (when area-code
+       (format "%02d" area-code))
+     (format "%s%s %s%s %s%s %s%s"
+            (split-string number "" t))
+     (when extension
+       (format "X%d" extension)))))
address@hidden lisp
+
+Again this only affects the display of numbers, not how they are
+stored in the database.
+
+Note that, while phone numbers themselves are stored as strings (they
+do not represent a quantity, after all), the country and area codes
+are stored as numbers, precisely so that they can be specialized on
+using @code{eql}.
+
+See the signatures of the other internationalized methods for how to
+use them.  The symbol specs for country codes and script names can
+also be specialized on with the @code{eql} specializer.
+
 @node Diary Integration
 @chapter Diary Integration
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]