Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ All notable changes to this project will be documented in this file. For change

- put future changes here
- Improve chinese translation
- Standardize on capitalizeFirstLetter meta key
- Standardize capitalizeFirstLetter meta key
- Change instructions object customization to options.hooks.tokenizedInstruction

# 0.0.7 2016-11-10

Expand Down
11 changes: 10 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ osrm-text-instructions transforms OSRM route responses into text instructions. I
### Javascript Usage

```
var osrmTextInstructions = require('osrm-text-instructions')('v5', 'en');
var version = 'v5';
var language = 'en';
var options = {};
var osrmTextInstructions = require('osrm-text-instructions')(version, language, options);

// make your request against the API

Expand All @@ -29,6 +32,12 @@ response.legs.forEach(function(leg) {
});
```

parameter | required? | values | description
---|----|----|---
`version` | required | `v5` | Major OSRM version
`language` | required | `en` `de` `zh-Hans` `fr` `nl` | Language identifier
`options.hooks.tokenizedIstruction` | optional | `function(instruction)` | A function to change the raw instruction string before tokens are replaced. Useful to inject custom markup for tokens

### Development
#### Architecture

Expand Down
56 changes: 29 additions & 27 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,40 @@
module.exports = function(version, language) {
module.exports = function(version, language, options) {
// load instructions
var instructions = require('./instructions').get(language);
if (Object !== instructions.constructor) throw 'instructions must be object';

if (!instructions[version]) { throw 'invalid version ' + version; }

var o = {
instructions: instructions,
return {
capitalizeFirstLetter: function(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
},
ordinalize: function(number) {
// Transform numbers to their translated ordinalized value
return this.instructions[version].constants.ordinalize[number.toString()] || '';
return instructions[version].constants.ordinalize[number.toString()] || '';
},
directionFromDegree: function(degree) {
// Transform degrees to their translated compass direction
if (!degree && degree !== 0) {
// step had no bearing_after degree, ignoring
return '';
} else if (degree >= 0 && degree <= 20) {
return this.instructions[version].constants.direction.north;
return instructions[version].constants.direction.north;
} else if (degree > 20 && degree < 70) {
return this.instructions[version].constants.direction.northeast;
return instructions[version].constants.direction.northeast;
} else if (degree >= 70 && degree < 110) {
return this.instructions[version].constants.direction.east;
return instructions[version].constants.direction.east;
} else if (degree >= 110 && degree <= 160) {
return this.instructions[version].constants.direction.southeast;
return instructions[version].constants.direction.southeast;
} else if (degree > 160 && degree <= 200) {
return this.instructions[version].constants.direction.south;
return instructions[version].constants.direction.south;
} else if (degree > 200 && degree < 250) {
return this.instructions[version].constants.direction.southwest;
return instructions[version].constants.direction.southwest;
} else if (degree >= 250 && degree <= 290) {
return this.instructions[version].constants.direction.west;
return instructions[version].constants.direction.west;
} else if (degree > 290 && degree < 340) {
return this.instructions[version].constants.direction.northwest;
return instructions[version].constants.direction.northwest;
} else if (degree >= 340 && degree <= 360) {
return this.instructions[version].constants.direction.north;
return instructions[version].constants.direction.north;
} else {
throw new Error('Degree ' + degree + ' invalid');
}
Expand Down Expand Up @@ -70,7 +69,7 @@ module.exports = function(version, language) {
if (!type) { throw new Error('Missing step maneuver type'); }
if (type !== 'depart' && type !== 'arrive' && !modifier) { throw new Error('Missing step maneuver modifier'); }

if (!this.instructions[version][type]) {
if (!instructions[version][type]) {
// Log for debugging
console.log('Encountered unknown instruction type: ' + type); // eslint-disable-line no-console
// OSRM specification assumes turn types can be added without
Expand All @@ -79,25 +78,25 @@ module.exports = function(version, language) {
type = 'turn';
}

// Use special this.instructions if available, otherwise `defaultinstruction`
// Use special instructions if available, otherwise `defaultinstruction`
var instructionObject;
if (this.instructions[version].modes[mode]) {
instructionObject = this.instructions[version].modes[mode];
} else if (this.instructions[version][type][modifier]) {
instructionObject = this.instructions[version][type][modifier];
if (instructions[version].modes[mode]) {
instructionObject = instructions[version].modes[mode];
} else if (instructions[version][type][modifier]) {
instructionObject = instructions[version][type][modifier];
} else {
instructionObject = this.instructions[version][type].default;
instructionObject = instructions[version][type].default;
}

// Special case handling
var laneInstruction;
switch (type) {
case 'use lane':
laneInstruction = this.instructions[version].constants.lanes[this.laneConfig(step)];
laneInstruction = instructions[version].constants.lanes[this.laneConfig(step)];

if (!laneInstruction) {
// If the lane combination is not found, default to continue straight
instructionObject = this.instructions[version]['use lane'].no_lanes;
instructionObject = instructions[version]['use lane'].no_lanes;
}
break;
case 'rotary':
Expand Down Expand Up @@ -148,6 +147,11 @@ module.exports = function(version, language) {
instruction = instructionObject.default;
}

var tokenizedInstructionHook = ((options || {}).hooks || {}).tokenizedInstruction;
if (tokenizedInstructionHook) {
instruction = tokenizedInstructionHook(instruction);
}

// Replace tokens
// NOOP if they don't exist
var nthWaypoint = ''; // TODO, add correct waypoint counting
Expand All @@ -157,18 +161,16 @@ module.exports = function(version, language) {
.replace('{exit_number}', this.ordinalize(step.maneuver.exit || 1))
.replace('{rotary_name}', step.rotary_name)
.replace('{lane_instruction}', laneInstruction)
.replace('{modifier}', this.instructions[version].constants.modifier[modifier])
.replace('{modifier}', instructions[version].constants.modifier[modifier])
.replace('{direction}', this.directionFromDegree(step.maneuver.bearing_after))
.replace('{nth}', nthWaypoint)
.replace(/ {2}/g, ' '); // remove excess spaces

if (this.instructions.meta.capitalizeFirstLetter) {
if (instructions.meta.capitalizeFirstLetter) {
instruction = this.capitalizeFirstLetter(instruction);
}

return instruction;
}
};

return o;
};
19 changes: 19 additions & 0 deletions test/index_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,23 @@ tape.test('v5 compile', function(t) {

assert.end();
});

t.test('respects options.instructionStringHook', function(assert) {
var v5Instructions = instructions('v5', 'en', {
hooks: {
tokenizedInstruction: function(instruction) {
return instruction.replace('{way_name}', '<blink>{way_name}</blink>');
}
}
});

assert.equal(v5Instructions.compile({
"maneuver": {
"type": "turn",
"modifier": "left"
},
"name": "Way Name"
}), 'Turn left onto <blink>Way Name</blink>');
assert.end();
});
});