Skip to content

Latest commit

 

History

History
902 lines (779 loc) · 28.6 KB

CAMINO.md

File metadata and controls

902 lines (779 loc) · 28.6 KB

Camino File Format

A "Camino" from the point of view of De Calixtinus is a coherent collection of locations, legs between locations and options and variants about how one might approach the route. It roughly corresponds to what one might expect if someone says, "I'm doing the Camino Français" or a guide-book, or one of the caminos downloaded from Buen Camino. The camino is encoded as a huge slab of JSON.

The basic camino file has the following format:

{
  "id": ...,
  "name": ...,
  "description": ...,
  "metadata" : {
    ...
  },
  "locations": [
    ...
  ],
  "legs": [
    ...
  ],
  "routes": [
    ...
  ],
  "route-logic": [
    ...
  ],
  "default-route": ...

The id, name, description and metadata entries for the header and gives descriptive information about the camino.

The locations and legs entries describe the various possible waypoints on the camino and the connections between them.

The routes, route-logic and default-route chunk the locations and legs into optional variants of the main, default route. Choosing routes can add extra possible locations to the trip or remove them if they are redundant. The consequences of multiple routes can get very complicated and the logic helps untangle what's in, what's out and where you can go.

Metadata

Metadata contains information about the camino file itself, or things like images that need appropriate attribution. In general, it allows you to encode information about the something, what it is for, where it came from, how current it is, etc. in a form corresponding to standards such as Dublin Core An example metadata entry is

"metadata": {
    "namespaces": [
      {
        "prefix": "dc",
        "namespace": "http://purl.org/dc/elements/1.1/"
      },
      {
        "prefix": "dcterms",
        "namespace": "http://purl.org/dc/terms/"
      }
    ],
    "statements": [
      {
        "term": "dcterms:title",
        "value": "Caminho Português",
        "lang": "pt"
      },
      {
        "term": "dcterms:modified",
        "value": "2024-04-09"
      },
      {
        "term": "dcterms:version",
        "value": "0.1.1"
      },
      {
        "term": "dcterms:license",
        "value": "https://creativecommons.org/licenses/by/4.0/"
      },
      {
        "term": "dcterms:source",
        "value": "https://www.editorialbuencamino.com/"
      },
    ]
  }

Terms in metadata statements are (preferably resolvable) URIs. The namespaces section allows you to define prefixes for these URIs so that you do not have to write out the entirety of a term. On the above example, dcterms:modified corresponds to http://purl.org/dc/terms/modified The dc: and dcterms: namespaces are automatically included and do not need to be declared.

The statements section is just a list of metadata terms and their values. The term and value entries must be present. An optional lang field allows you to specify the language the value is in.

You can have multiple statements all using the same term. For example, multiple source statements are perfectly sensible.

Localisation

Many parts of a camino file can be localised, with different names and descriptions appearing depending on the requested languages.

Supported Languages

Language Code Messages Camino Date & Time
Basque eu N N Y
English en Y Y Y
French fr N N Y
Gallacian ga N Y Y
Portuguese pt N Y Y
Spanish es N Y Y

Not all languages are fully supported. Messages mean that labels and text on the web pages can be expressed in the requested language. Languages supported on the Camino means that there are some names, descriptions etc. specifically in a Camino file. Date & Time means that months and days of the week have language-specific versions.

Tagged Text

The key element for localisation is a piece of tagged text where a language-tag of the form "@code" at the end of the text denotes the language. For example, mystery number one@en is in English and misterio número uno@es is in Spanish.

If there is no tag, then the tag is assumed to be the universal tag *.

Localised Text

Tagged text can be grouped together to provide localisable variants by using a JSON list. For example:

{
  "name": [
    "Lisboa@pt",
    "Lisbon@en"
  ]
}

means that the name is Lisboa in Portuguese and Lisbon in English.

If there is no matching language, then the first element of the list is chosen. Note that including an entry with a universal tag will always match a requested language.

If there is only one entry, then a string can be used instead of an array. For example,

"name": "Statue of King Denis I@en"

and

"name": [
  "Statue of King Denis I@en"
]

are equivalent.

Localised URLs

Localised URLs allow locale-specific links to external resources. A simple URL can be written as a string, for example

"about": "https://wikipedia.org/wiki/Lisbon"

A group of localised URLs can be structured as a list, for example

"about": [
    {
        "locale": "pt",
        "url": "https://pt.wikipedia.org/wiki/Lisboa",
        "title": "Lisboa"
    }.
    {
        "locale": "en",
        "url": "https://en.wikipedia.org/wiki/Lisbon",
        "title": "Lisbon"
    }.
]

In the latter case, the element of each entry are:

  • locale A language code
  • url: The localised URL
  • title An optional title giving link or title text

Description

Descriptive information appears in multiple places and gathers together descriptive text, images, additional notes and links to external information. In general, if there is a description field then it will take this format.

  • summary A simple summary line, which may be localised. If absent the text is used where a summary is needed.
  • text Descriptive text, which may be localised. If descriptive text is used, then the summary is not.
  • about A URL link, which may be localised
  • image An image associated with the description. See below
  • notes A list of additional notes. See below

A description field can also be a simple tagged string, in which case it will be created as a mostly empty description with text.

Images

Images allow an image to be linked to descriptive text. In general a thumbnail of the image is shown alongside the description; clicking on the thumbnail opens the full-sized image in a dialog box.

Image URLs may be relative, in which case they are resolved against the images URL in the configuration.

  • source A URL to the full-size image source.
  • thumbnail An optional URL to a thumbnail of the image.
  • title An image title, which may be localised
  • metadata Metadata about the image. This should contain dcterms for things like rights, licensing etc.

Since images are likely to have come from a third party, the metadata statement can be used to provide information on citation, attribution and licensing. These can be expressed in Dublin Core as dcterms or dc URIs and a suitable attribution statement will be assembled out of the elements.

Example image JSON, for an image drawn from Wikipedia, is shown below

{
  "source": "P/P-P1-Lisbon.jpg",
  "thumbnail": "P/P-P1-Lisbon-thumbnail.jpg",
  "title": "Praça do Comércio@pt",
  "metadata": {
    "statements": [
      {
        "term": "dcterms:creator",
        "value": "Berthold Werner"
      },
      {
        "term": "dcterms:rightsHolder",
        "value": "Wikimedia Commons"
      },
      {
        "term": "dcterms:license",
        "value": "CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0>"
      },
      {
        "term": "dcterms:source",
        "value": "https://commons.wikimedia.org/wiki/File:Lisbon_Pra%C3%A7a_do_Com%C3%A9rcio_BW_2018-10-03_13-33-44_s.jpg"
      }
    ]
  }
}

Notes

Notes represent additional information that can be drawn away from the more general descriptive text. There are four types of notes: Information, Warning, Address, Directions with each note type providing a visual indication of the sort of thing the note is about.

If the type is absent, Information is assumed and a piece of tagged text is assumed to be an information note. Otherwise, a note is a JSON object with a type and text field. For example

{
  "notes": [
    "The crossing is the only ",
    {
      "type": "Directions",
      "text": "The crossing can be seen from the overpass. Go down the stairs to the left.@en"
    }
    {
      "type": "Warning",
      "text": [
        "busy road@en",
        "errepide okupatua@eu"
      ]
    }
  ]
}

contains a simple information note in English, directions in English and a warning in both English and Basque.

Calendar and Times

Some items occur only on certain days or at particular times.

A calendar can be either daily (the default by implication) or occur on certain days of the week or month, or certain months in the year.

The types of calendar are:

[
  {
    "type": "daily"
  },
  {
    "type": "weekly",
    "days": [ "monday", "friday"]
  },
  {
    "type": "monthly",
    "days": [ 8, 15 ]
  },
  {
    "type": "yearly",
    "months": [ 5, 6, 7 ]
  },
  {
    "type": "day-of-year",
    "days": [ "04-21", "10-23" ]
  },
  {
    "type": "range",
    "from": {
      "type": "day-of-year",
      "days": ["01-01"]
    },
    "to": {
      "type": "weekly",
      "days": ["friday"]
    }
  },
  {
    "type": "union",
    "calendars": [
      {
        "type": "named",
        "key": "Christmas"
      },
      {
        "type": "named",
        "key": "BoxingDay"
      }
    ]
  },
  {
    "type": "intersection",
    "calendars": [
      {
        "type": "monthly",
        "days": [ 1, 8, 15 ]
      },
      {
        "type": "weekly",
        "days": [ "monday", "wednesday"]
      }
    ]
  },
  {
    "type": "except",
    "calendar": [
      {
        "type": "yearly",
        "months": [ 1, 2, 3 ]
      }
    ]
  },
  {
    "type": "nth-day-after",
    "nth": 4,
    "calendar": [
      {
        "type": "monthly",
        "days": [ 1, 14, 21 ]
      }
    ]
  },
  {
    "type": "nth-weekday",
    "nth": "Last",
    "day": "friday"
  },
  {
    "type": "nth-weekday-after",
    "nth": 2,
    "day": "friday",
    "calendar": {
      "type": "named",
      "key": "Christmas"
    }
  },
  {
    "type": "list",
    "dates": [
      "2023-10-11",
      "2024-10-15",
      "2025-10-09",
      "2026-10-14"
    ]
  },
  {
    "type": "named",
    "key": "EasterSunday"
  },
  {
    "type": "public-holiday",
    "region": "Galicia"
  },
  {
    "type": "conditional",
    "calendar":     {
      "type": "weekly",
      "days": [ "monday", "friday"]
    },
    "condition": "Except when Friday is the last day of the month.@en"
  }
]
  • Weekly calendars occur on the listed days of the week. The days of the week are in English and all lower-case. In the example, the venue is open only Monday and Friday.
  • Monthly calendars occur on specific days of the month. In the example, the venue is open only on the 8th and 15th of the month.
  • Yearly calendars occur in specific months of the year. The months are month numbers, counting from 0 for January. In the sample, the venue is open only in June, July and August.
  • Day of year calendars give dates that repeast every year, with days given in month-day format. In the example, the calendar specifies the 21st of April and the 23rd of October every year.
  • Range calendars specify a range from the start of one calendar to the end of another, relative to the start point. In the example, the range is from the 1st of January each year until the following (or on) Friday.
  • Union calendars are a collection of other calendars. Any matching calendar indicates a date in the calendar. In the example, both Christmas and Boxing Day match.
  • Intersection calendars are a collection of other calendars. All the component calendars must match a date for it to be in the intersection. In the example, the intersection is the 1st, 8th and 15th of the month when they fall on a Monday or Wednesday.
  • An except calendar inverts the calendar. Any data not in the component calendar is a match. In the example, January, February and March are excluded but any other day is in the calnedar.
  • The Nth-day-after calendar fits a data to a number of days after (or before, if the number is negative) a reference calendar. In the example, the calendar days 4 days after the 1st, 14th or 21st of the month.
  • The Nth-weekday specifies dates such as "second Tuesday in the month". The nth value can be First, Second, Third, Fouth Fifth or Last, with the fifth being the same as the fourth if there is no fifth. In the example, an even falls on the last Friday of every month.
  • The Nth-weekday-after calndar specifies the nth day of week after a reference calendar. In the example, the calendar specifies the second Friday after Christmas. If the value is negative then it means the nth weekday before the reference calendar.
  • A list calendar just gives up trying to specify a rule and just gives a list of dates in ISO-8601 format. In the example, different days in October are specified for a number of years.
  • A named calendar has an external specification, usually in the configuration file. The calendar has a key that can be used to look up the calendar definition. These calndars can be configured to have locale-specific names (eg. Christmas or Navidad) and use a key, rather than a name. The example refers to Easter Sunday, which moves about the calendar and is usually configured as a list.
  • A public holiday calendar refers to all the public holidays in a region, given by a region identifier. The example refers to all public holidays take in Galicia, including Spanish national holidays.
  • A conditional calendar takes another calendar and adds a text condition.

Times give the hour of the day that something happens, is open, etc. Times are represented by a string containing pairs of start and finish times. The times are local times using the 24-hour clock. Start and finish times are separated by a - and ranges by a ,. For example: "0830-1200,1400-1930" means 8:30am to 12 noon and then 2pm to 7:30pm.

The special text "open" means open all hours. The special text "closed" means that the location is closed. This can be used, in conjunction with hours (below) to indicate exceptions.

Hours give the opening hours or event times for something and usually represent a paired calendar and set of times. If multiple hours are given, then the first one that matches the calendar applies. For example:

"hours": [
    {
      "calendar": {
        "type": "named",
        "key": "Christmas"
      },
      "hours": "closed"
    },
    {
      "calendar": {
        "type": "weekly",
        "days": [ "monday", "tuesday", "wednesday", "thursday" ]
      },
      "hours": "1000-1430,1630-200"
    }
]

means something that is open on weekdays from 10am to 2:30pm and then 4:30pm to 8pm, except on Christmas Day, when it is closed.

Header

The header contains descriptive information about the camino

  • id The camino identifier. See below
  • name A short name for the camino. TBD Localised variants
  • description Descriptive information about the camino.
  • metadata See above

Identifiers and References

Most significant parts of the camino have an identifier, given by the id JSON field. Identifiers must be globally unique, since users may mix up preferences across multiple caminos. The convention used in the supplied file is to have a single identifier for the camino itself and then this is used as a prefix for the location and route identifiers. For example, if the identifier of the camino is "F" then the identifier for a location might be "F-M001" with the "F-" prefix ensuring that another camino doesn't have the same location identifier.

In most cases, once a location or route has been defined, it can be referred to elsewhere by its identifier. So, for example, if a route wants to list the location above, it simply needs to put "F-M001", not repeat the location information. The camino parser will sort out all the references when it reads the file.

Locations

Locations describe potential stops and waypoints on the camino route. They are usually things like towns or villages but can be something like a bridge, a monastery or just a generic point of interest. An example location is:

{
  "id": "P-P15",
  "name": "Azambuja",
  "type": "Town",
  "position": { "latitude": 39.0695, "longitude": -8.8667 },
  "services": ["BicycleRepair", "Restaurant", "Groceries", "Pharmacy", "Medical", "Bank", "Train", "Bus" ],
  "accommodation": [
    {
      "name": "Azambuja Pilgrims Hostel",
      "type": "PilgrimAlbergue",
      "services": ["Handwash"],
      "sleeping": ["Shared"]
    },
    {
      "name": "Residencial Flôr da Primavera",
      "type": "PrivateAlbergue",
      "services": ["Kitchen", "WiFi", "Bedlinen", "Towels"],
      "sleeping": ["Single", "DoubleWC", "Triple"]
    },
    {
      "name": "Casa da Rainha",
      "type": "PrivateAlbergue",
      "services": ["WiFi", "Bedlinen", "Towels"],
      "sleeping": ["Single", "DoubleWC"]
    }
  ]
}

The elements are:

  • id The globally unique identifier for the location
  • name The name of the location
  • description Optional descriptive information
  • type The type of location. See below
  • position The position of the location in decimal latitude and longitude.
  • services A list of the publicly available services at the location. See below.
  • accommodation A list of the accommodation options. See below
  • pois A list of points of interest. See below
  • events A list of local events. See below

When you are constructing a location, the position can be difficult. Generally a latitude/longitude accurate to 5 decimal places identifies the position to within a metre. That enables you to place the location on a suitable road or intersection. What the "position" of a location actually is tends to be a matter of opinion. It seems to be a good idea to place locations at municipal albergues, if one exists, intersections, churches, town squares and the like.

Types, Services, etc.

Things like location type, services, bedding, travel types and the like are encoded as strings. These correspond to the values in the main camino model.

Accommodation

An accommodation entry gives an albergue, hotel, hostel and the like. A typical accommodation entry looks like:

{
  "name": "Residencial Flôr da Primavera",
  "type": "PrivateAlbergue",
  "services": ["Kitchen", "WiFi", "Bedlinen", "Towels"],
  "sleeping": ["Single", "DoubleWC", "Triple"]
}
  • The name is the name of the guest house, camp site, hotel, etc.
  • The type is the type of accommodation. See above
  • The services lists the services available to guests. See above. These can overlap with public services.
  • sleeping lists the types of sleeping arrangements available. See above

Generic Accommodation

Places like cities tend to have too many accommodation options to list. Or you may just be feeling lazy. Instead of listing specific accommodation, you can list generic accommodation options instead by just giving the types of accommodation. For example:

"accommodation": [ "PrivateAlbergue", "Hotel" ]

Creates a generic private albergue and a hotel with typical services and sleeping arrangements.

Points of Interest

Points of interest (PoIs) are locations not directly connected with travelling the Camino but which might be of interest to pilgrims on the way: churches, cathedrals, statues, museums, parks etc. Generally, PoIs have the same types as locations and descriptive information. They may also have calendar and times information and attached events.

And example PoI is

{
  "name": [
    "Museu Nacional do Azulejo@pt",
    "National Tile Museum@en"
  ],
  "type": "Museum",
  "position": { "latitude": 38.72508, "longitude": -9.11347 },
  "hours": [
    {
      "calendar": {
        "type": "weekly",
        "days": [ "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday" ]
      },
      "hours": "1000-1800"
    }
  ]
}

The fields are

  • name The name of the PoI, possibly localised
  • description Any optional descriptive information
  • type The PoI (location) type
  • position The latitude and longitude of the PoI
  • hours An optional set of opening hours showing when the PoI is open
  • events An optional list of events associated with the PoI

Events

Events are things like festivals or ceremonies that might interest a pilgrim, if they happen to be there at the right time. Events can be attached to both locations, for things like a town festival, or points of interest, for things like pilgrim masses and blessings. An example event is

{
  "name": "Pilgrim's Mass",
  "type": "PilgrimMass",
  "hours": "0730-0830,0930-1030,1200-1300,1930-2030"
}

The fields are

  • name The name of the event, possibly localised
  • description Any optional descriptive information
  • type The event type
  • hours Optional hours showing when the event occurs

Legs

Legs link locations. A leg typically describes the amount of effort needed to get from the start of the leg to its finish. A typical leg is:

{
  "from": "P-P5",
  "to": "P-P8",
  "distance": 3.78,
  "ascent": 25,
  "descent": 5
}

This describes a leg on a generally navigable road or trail with a distance of 3.78km, a total ascent of 25m and a total descent of 5m.

Legs should be generally short enough that collecting total ascent and descent into two figures passes the sniff test. The planner will divide the ascent and descent into two segments and calculate slop and effort based on that approximation.

A single location can have multiple legs leaving from it and also multiple legs arriving to it. The planner chooses between alternative sequences of legs based on minimum penance.

A more complex leg can include travel type and alter the time and distance calculations. For example, a leg by ferry, rather than walking, might be:

{
  "type": "FerryLink",
  "from": "P-E22",
  "to": "P-P258",
  "time": 2.5,
  "penance": 2.0,
  "distance": 0,
  "ascent": 0,
  "descent": 0,
  "description": "Pilgrim's ferry"
}
  • type gives the type of travel. See above
  • time gives an explicit time of travel, rather than calculating it from fitness, distances etc. Generally, if you use time, set the distance, ascent and descent to zero.
  • penance gives an extra amount of penance to apply when using this leg. As well as time-based legs, such as the one above, you can use this to denote a particularly nasty part of the route for some reason or other and use it to influence the planner. For example, out of two routes, the most direct passes though a particularly miserable industrial area.
  • description Allow you to add additional description to the leg.

Routes

Routes are collections of locations grouped together into named optional variants of the main route. For example, the Spiritual Variant takes the pilgrim away from the main route and follows the path of St. James. An example route is:

{
  "id": "P-RS",
  "name": "Variante Espiritual",
  "description": "The Spiritual Variant of the main route that follows the last part of the journey of the remains of the Apostle St.James. The variant ends with a boat trip up the Río Ulla",
  "locations": [
    "P-E1", "P-E2", "P-E3", "P-E4", "P-E5", "P-E6", "P-E7", "P-E8", "P-E9", "P-E10",
    "P-E11", "P-E12", "P-E13", "P-E14", "P-E15", "P-E16", "P-E17", "P-E18", "P-E19", "P-E20",
    "P-E21", "P-E22"
  ],
  "stops": [
    "P-E21"
  ],
  "palette": {
    "colour": "F00810"
  }
}
  • id The route identifier
  • name The route name
  • description a long-form description of the route
  • locations a list of the locations (by identifier) that are included in the route. Using a route usually also excludes locations from the pilgrimage by bypassing them. Additional inclusions and exclusions can get very complicated and are handled by the route logic section.
  • starts a list of common start points for people beginning their pilgrimage
  • finishes A list of common finish points for people ending their pilgrimage This is usually set to Santiago de Compostella in the default route.
  • stops Suggested stop points. These are usually places that have some sort of significance and where it would be a shame for the planner to just propel the pilgrim past.
  • palette The colour denoting the route. The text-colour field can be added to provide a more contrasting text colour, if needed.

Locations not explicitly listed in other routes are assigned to the specified default route. The default route is always one of the possible routes selected by the planner.

Route Logic

When routes are combined, things can get complicated as some locations become accessible, some become unreachable and other routes become options. The route logic section describes the effect of various route combinations. An example route logic entry is:

{
  "condition": {
    "and": [
      {
        "not": "P-RT1"
      },
      "P-RT2"
    ]
  },
  "description": "Transferring from the central route down to the coastal route",
  "requires": [ "P-RC" ],
  "allows": [ "P-RT3", "P-RT4" ],
  "prohibits": [ "P-RL" ],
  "include": [
    "P-P140", "P-P141", "P-P142", "P-P143", "P-P144", "P-P145", "P-P146", "P-P147", "P-P148", "P-P149",
    ...
  ],
  "exclude": [
              "P-C2",   "P-C3",   "P-C4",   "P-C5",   "P-C6",   "P-C7",   "P-C8",   "P-C9",   "P-C10",
    "P-C11",  "P-C12",  "P-C13",  "P-C14",  "P-C15",  "P-C16",  "P-C17",
    "P-P155", "P-P156", "P-P157", "P-P158", "P-P159",
    ...
  ]
}
  • condition The conditions under which this particular set of alterations applies. See below
  • description An optional description of what this is intended to capture.
  • requires A list of other routes that are required to be present for this combination to make sense. The default route is always included.
  • allows A list of additional routes that become possible under these conditions. Usually, this means the route now passes the point where these options diverge.
  • prohibits A list of routes that become impossible to use under these conditions. Usually, this means that those routes have been bypassed by the current combination.
  • include Additional locations to include
  • exclude Locations to remove from consideration

Route logic includes and excludes are applied in sequence. It is quite possible to have locations added by one piece of route logic and then removed by a subsequent piece.

Conditions

Conditions are boolean algebra expressions of combinations of routes. The possible expressions are:

  • id True if the route with id has been selected.
  • "and": [ ... ] All listed conditions must be true
  • "or": [ ... ] At least on listed conditions must be true
  • "not": c The condition must be false
  • true Always true. (Not terribly useful but may be used for machine-generated conditions)
  • false Always false

Conditions can be simple, so "condition": "R1" means this route logic applies if the route R1 has been selected. Complex conditions can be nested so "either R3 or R2 and not R1 are selected" can be expressed as:

{
  "or": [
    "R3",
    "and": [
      {
        "not": "R1"
      },
      "R2"
    ]
  ]
}