Skip to content

Commit

Permalink
Add docs
Browse files Browse the repository at this point in the history
  • Loading branch information
kipcole9 committed Apr 23, 2024
1 parent b33c8c4 commit 19e03fa
Show file tree
Hide file tree
Showing 8 changed files with 615 additions and 46 deletions.
106 changes: 106 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: Elixir CI

# Define workflow that runs when changes are pushed to the
# `main` branch or pushed to a PR branch that targets the `main`
# branch. Change the branch name if your project uses a
# different name for the main branch like "master" or "production".
on:
push:
branches: [ "main" ] # adapt branch for project
pull_request:
branches: [ "main" ] # adapt branch for project

# Sets the ENV `MIX_ENV` to `test` for running tests
env:
MIX_ENV: test

permissions:
contents: read

jobs:
test:
# Set up a Postgres DB service. By default, Phoenix applications
# use Postgres. This creates a database for running tests.
# Additional services can be defined here if required.
# services:
# db:
# image: postgres:12
# ports: ['5432:5432']
# env:
# POSTGRES_PASSWORD: postgres
# options: >-
# --health-cmd pg_isready
# --health-interval 10s
# --health-timeout 5s
# --health-retries 5

runs-on: ubuntu-latest
name: Test on OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}}
strategy:
# Specify the OTP and Elixir versions to use when building
# and running the workflow steps.
matrix:
otp: ['26.2'] # Define the OTP version [required]
elixir: ['1.16.2-otp-26'] # Define the elixir version [required]
steps:
# Step: Setup Elixir + Erlang image as the base.
- name: Set up Elixir
uses: erlef/setup-beam@v1
with:
otp-version: ${{matrix.otp}}
elixir-version: ${{matrix.elixir}}

# Step: Check out the code.
- name: Checkout code
uses: actions/checkout@v3

# Step: Define how to cache deps. Restores existing cache if present.
- name: Cache deps
id: cache-deps
uses: actions/cache@v3
env:
cache-name: cache-elixir-deps
with:
path: deps
key: ${{ runner.os }}-mix-${{ env.cache-name }}-${{ hashFiles('**/mix.lock') }}
restore-keys: |
${{ runner.os }}-mix-${{ env.cache-name }}-
# Step: Define how to cache the `_build` directory. After the first run,
# this speeds up tests runs a lot. This includes not re-compiling our
# project's downloaded deps every run.
- name: Cache compiled build
id: cache-build
uses: actions/cache@v3
env:
cache-name: cache-compiled-build
with:
path: _build
key: ${{ runner.os }}-mix-${{ env.cache-name }}-${{ hashFiles('**/mix.lock') }}
restore-keys: |
${{ runner.os }}-mix-${{ env.cache-name }}-
${{ runner.os }}-mix-
# Step: Download project dependencies. If unchanged, uses
# the cached version.
- name: Install dependencies
run: mix deps.get

# Step: Compile the project treating any warnings as errors.
# Customize this step if a different behavior is desired.
- name: Compiles without warnings
run: mix compile --warnings-as-errors

# Step: Check that the checked in code has already been formatted.
# This step fails if something was found unformatted.
# Customize this step as desired.
# - name: Check Formatting
# run: mix format --check-formatted

# Step: Execute the tests.
- name: Run tests
run: mix test

# Step: Execute dialyzer.
- name: Run dialyzer
run: mix dialyzer
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Cldr Person Names v0.1.0

This is the changelog for `:ex_cldr_person_names` v0.1.0 released on ____, 2023. For older changelogs please consult the release tag on [GitHub](https://github.com/elixir-cldr/cldr_person_names/tags)
This is the changelog for `ex_cldr_person_names` v0.1.0 released on April 23rd, 2023. For older changelogs please consult the release tag on [GitHub](https://github.com/elixir-cldr/cldr_person_names/tags)

### Enhancements

Expand Down
74 changes: 68 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ end

Note the `:provider` configuration key which is required to include `Cldr.PersonName` in order for person name formatting to be configured for this backend.

## Installation
### Installation

Note that `:ex_cldr_person_names` requires Elixir 1.11 or later.
Note that `:ex_cldr_person_names` requires Elixir 1.12 or later.

Add `ex_cldr_person_names` as a dependency to your `mix` project:

Expand All @@ -42,12 +42,74 @@ then retrieve `ex_cldr_person_names` from [hex](https://hex.pm/packages/ex_cldr_
mix deps.get
mix deps.compile

## Examples
## Presentations

### Cldr.PersonName struct
* Launch presentation at the [Elixir Sydney Meetup](https://www.youtube.com/watch?v=pBR-n_dA3lo) in February 2024.
* The slides from the launch presetnation are available in [Powerpoint format](https://github.com/elixir-cldr/cldr_person_names/raw/main/presentations/Person%20Name%20Formatting.pptx) and [PDF format](https://github.com/elixir-cldr/cldr_person_names/raw/main/presentations/Person%20Name%20Formatting.pdf)

### Formatting
The livebook used at the launch presentation is also available.

#### When the name locale differs from the formatting locale
[![Run in Livebook](https://livebook.dev/badge/v1/blue.svg)](https://livebook.dev/run?url=https%3A%2F%2Fraw.githubusercontent.com%2Felixir-cldr%2Fcldr_person_names%2Fmain%2Flivebooks%2Fperson_name_formatting_explorer.livemd)

## Why Person Name Formatting?
<!-- Split --->
`ex_cldr_person_names` provides formatting for person names, such as John Smith or 宮崎駿 based upon the [CLDR Person Names](https://www.unicode.org/reports/tr35/tr35-personNames.html) specification. These use patterns to show how a name object (for example, from a database) should be formatted for a particular locale. Name data has fields for the parts of people’s names, such as a given name field with a value of “Maria”, and a surname field value of “Schmidt”.

There is a wide variety in the way that people’s names appear in different languages.

* People may have a different number of names, depending on their culture—they might have only one name (“Zendaya”), two (“Albert Einstein”), or three or more.
* People may have multiple words in a particular name field, eg “Mary Beth” as a given name, or “van Berg” as a surname.
* Some languages, such as Spanish, have two surnames (where each can be composed of multiple words).
* The ordering of name fields can be different across languages, as well as the spacing (or lack thereof) and punctuation.
* Name formatting needs to be adapted to different circumstances, such as a need to be presented shorter or longer; formal or informal context; or when talking about someone, or talking to someone, or as a monogram (JFK).

The `ex_cldr_person_names` functionality is targeted at formatting names for typical usage on computers (e.g. contact names, automated greetings, etc.), rather than being designed for special circumstances or protocol, such addressing royalty. However, the structure may be enhanced in the future when it becomes clear that additional features are needed for some languages.

### Not in scope

The following features are currently out of scope for Person Names formating:

* Grammatical inflection of formatted names.
* Context-specific cultural aspects, such as when to use “-san” vs “-sama” when addressing a Japanese person.
* Providing locale-specific lists of titles, generation terms, and credentials for use in pull-down menus or validation (Mr, Ms., Mx., Dr., Jr., M.D., etc.).
* Validation of input, such as which fields are required, and what characters are allowed.
* Combining alternative names, such as multicultural names in Hong Kong "Jackie Chan Kong-Sang”, or ‘Dwayne “The Rock” Johnson’.
* More than two levels of formality for names.
* Parsing of names.
* Parsing of name strings into specific name parts such as given and given2. A name like "Mary Beth Estrella" could conceivably be any of the following.

| Given Name | Other Given Names | Surname | Other Surnames |
| ---------- | ----------------- | ------- | -------------- |
| Mary | Beth | Estrella | |
| Mary Beth | | Estrella | |
| Mary | | Beth Estrella | |
| Mary | | Beth | Estrella |

* Parsing out the other components of a name in a string, such as surname prefixes (Tussenvoegsel in Dutch).

## Structure of a Person Name

Person name formatting depends on data supplied by a `t:Cldr.PersonName.t/0` data structure. A `Cldr.PersonName` behaviour and a `Cldr.PersonName.Format` protocol are provided to support easy integration with existing data structures.

The `t:Cldr.PersonName.t/0` struct is composed of one or more name parts:

* `title` - a string that represents one or more honorifics or titles, such as “Mr.”, or “Herr Doctor”.
* `given_name` - usually a name given to someone that is not passed to a person by way of parentage.
* `informal_given_name` - usually either a nickname or a shortened form of the given name that is used to address a person informally.
* `other_given_names` - name or names that may appear between the first given name string and the surname. In the West, this may be a middle name, in Slavic regions it may be a patronymic name, and in parts of the Middle East, it may be the nasab (نسب) or series of patronymics.
* `surname` - usually the family name passed to a person that indicates their family, tribe, or community. In most Western languages, this is known as the last name.
* `other_surnames` - in some cultures, both the parent’s surnames are used and need to be handled separately for formatting in different contexts.
* `generation` - a string that represents a generation marker, such as “Jr.” or “III”.
* `credentials` - a string that represents one or more credentials or accreditations, such as “M.D.”, or “MBA”.
* `locale` - defines the `t.Cldr.LanguageTag.t/0` of a name. This allows different formatting of a name depending on whether it is being formatted for its native locale, or for a different locale.
* `name_order` - an atom indicating the preferred name order for this name. The valid values are `:given_first`, `:surname_first`, `:sorting`. By default, `ex_cldr_person_names` will derive the name order based upon the name's locale and the formatting locale.

**At mininum, a `given_name` is required. All other data elements are optional**.

## Integration with Existing Data

Its clear that existing person name data isn't going to be neatly structured in a `t:Cldr.PersonName.t/0`. `ex_cldr_person_names` provides two mechanisms to integrate existing data:

* The `Cldr.PersonName` behaviour can be used when the developer has control over the data structure, and the data structure is an Elixir `struct`. This is the recommended approach when the developer has control over the struct module. In this case, [callbacks](Cldr.PersonName#callbacks) can be implemented for the `struct` that return the person name data to the formatter. The formatter implementation will call `Cldr.PersonName.cast_to_person_name/1` using the callbacks.

* The `Cldr.PersonName.Format` protocol is useful when the developer has no control over the existing data structure. Therefore the `Cldr.PesonName.Format.to_string/2` function can be called and the protocol implementation is expected to craft a structure compatible with - or actually is - a `t:Cldr.PersonName.t/0` struct, and then calls the `Cldr.PersonName.to_string/2` function. Since `t:Cldr.PersonName.t/0` implements the `Cldr.PersonName.Format` protocol, `Cldr.PersonName.Format.to_string/2` can be used consistently throughout an application if preferred.
Loading

0 comments on commit 19e03fa

Please sign in to comment.