gtfs-to-html 2.2.0 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "gtfs-to-html",
3
- "version": "2.2.0",
3
+ "version": "2.3.2",
4
4
  "private": false,
5
- "description": "Build human readable transit timetables as HTML or PDF from GTFS",
5
+ "description": "Build human readable transit timetables as HTML, PDF or CSV from GTFS",
6
6
  "keywords": [
7
7
  "transit",
8
8
  "gtfs",
@@ -38,30 +38,48 @@
38
38
  "@turf/helpers": "^6.5.0",
39
39
  "@turf/simplify": "^6.5.0",
40
40
  "archiver": "^5.3.0",
41
- "chalk": "^4.1.2",
42
- "cli-table": "^0.3.6",
41
+ "chalk": "^5.0.0",
42
+ "cli-table": "^0.3.11",
43
43
  "copy-dir": "^1.3.0",
44
- "express": "^4.17.1",
45
- "gtfs": "^3.1.2",
44
+ "csv-stringify": "^6.0.4",
45
+ "express": "^4.17.2",
46
+ "gtfs": "^3.2.2",
46
47
  "js-beautify": "^1.14.0",
47
48
  "lodash-es": "^4.17.21",
48
49
  "moment": "^2.29.1",
49
50
  "morgan": "^1.10.0",
50
- "pretty-error": "^3.0.4",
51
+ "pretty-error": "^4.0.0",
51
52
  "pug": "^3.0.2",
52
- "puppeteer": "^10.4.0",
53
+ "puppeteer": "^13.0.1",
53
54
  "sanitize-filename": "^1.6.3",
54
55
  "sqlstring": "^2.3.2",
55
56
  "timer-machine": "^1.1.0",
56
57
  "toposort": "^2.0.2",
57
58
  "untildify": "^4.0.0",
58
- "yargs": "^17.2.1"
59
+ "yargs": "^17.3.1"
59
60
  },
60
61
  "devDependencies": {
61
- "eslint": "^8.0.1",
62
- "eslint-config-xo": "^0.39.0"
62
+ "eslint": "^8.5.0",
63
+ "eslint-config-prettier": "^8.3.0",
64
+ "eslint-config-xo": "^0.39.0",
65
+ "husky": "^7.0.4",
66
+ "prettier": "^2.5.1",
67
+ "pretty-quick": "^3.1.3"
63
68
  },
64
69
  "engines": {
65
70
  "node": ">= 12.14.0"
71
+ },
72
+ "release-it": {
73
+ "github": {
74
+ "release": true
75
+ },
76
+ "plugins": {
77
+ "@release-it/keep-a-changelog": {
78
+ "filename": "CHANGELOG.md"
79
+ }
80
+ }
81
+ },
82
+ "prettier": {
83
+ "singleQuote": true
66
84
  }
67
85
  }
@@ -3,7 +3,11 @@ body {
3
3
  color: #666;
4
4
  }
5
5
 
6
- h1, h2, h3, h4, h5 {
6
+ h1,
7
+ h2,
8
+ h3,
9
+ h4,
10
+ h5 {
7
11
  color: #333;
8
12
  }
9
13
 
@@ -79,7 +83,7 @@ a:hover {
79
83
  }
80
84
 
81
85
  .timetable .table-container::-webkit-scrollbar-track {
82
- background-color: rgba(57, 57, 57, .2);
86
+ background-color: rgba(57, 57, 57, 0.2);
83
87
  border-radius: 4px;
84
88
  }
85
89
 
@@ -105,47 +109,47 @@ a:hover {
105
109
  padding: 0;
106
110
  }
107
111
 
108
- .timetable table>thead>tr>th,
109
- .timetable table>tbody>tr>th,
110
- .timetable table>tfoot>tr>th,
111
- .timetable table>thead>tr>td,
112
- .timetable table>tbody>tr>td,
113
- .timetable table>tfoot>tr>td {
112
+ .timetable table > thead > tr > th,
113
+ .timetable table > tbody > tr > th,
114
+ .timetable table > tfoot > tr > th,
115
+ .timetable table > thead > tr > td,
116
+ .timetable table > tbody > tr > td,
117
+ .timetable table > tfoot > tr > td {
114
118
  padding: 8px;
115
119
  line-height: 1.42857143;
116
120
  vertical-align: top;
117
121
  border: 1px solid #dddddd;
118
122
  }
119
123
 
120
- .timetable table>thead>tr>th {
124
+ .timetable table > thead > tr > th {
121
125
  vertical-align: top;
122
126
  border-bottom: 2px solid #dddddd;
123
127
  }
124
128
 
125
- .timetable table>caption+thead>tr:first-child>th,
126
- .timetable table>colgroup+thead>tr:first-child>th,
127
- .timetable table>thead:first-child>tr:first-child>th,
128
- .timetable table>caption+thead>tr:first-child>td,
129
- .timetable table>colgroup+thead>tr:first-child>td,
130
- .timetable table>thead:first-child>tr:first-child>td {
129
+ .timetable table > caption + thead > tr:first-child > th,
130
+ .timetable table > colgroup + thead > tr:first-child > th,
131
+ .timetable table > thead:first-child > tr:first-child > th,
132
+ .timetable table > caption + thead > tr:first-child > td,
133
+ .timetable table > colgroup + thead > tr:first-child > td,
134
+ .timetable table > thead:first-child > tr:first-child > td {
131
135
  border-top: 0;
132
136
  }
133
137
 
134
- .timetable table>tbody+tbody {
138
+ .timetable table > tbody + tbody {
135
139
  border-top: 2px solid #dddddd;
136
140
  }
137
141
 
138
- .timetable table>thead>tr>th,
139
- .timetable table>thead>tr>td {
142
+ .timetable table > thead > tr > th,
143
+ .timetable table > thead > tr > td {
140
144
  border-bottom-width: 2px;
141
145
  }
142
146
 
143
- .timetable table>tbody>tr:nth-of-type(odd) {
147
+ .timetable table > tbody > tr:nth-of-type(odd) {
144
148
  background-color: #f9f9f9;
145
149
  }
146
150
 
147
151
  .table-responsive {
148
- min-height: .01%;
152
+ min-height: 0.01%;
149
153
  overflow-x: auto;
150
154
  }
151
155
 
@@ -158,24 +162,26 @@ a:hover {
158
162
  }
159
163
 
160
164
  .route-color-swatch {
161
- width: 26px;
165
+ min-width: 26px;
162
166
  height: 26px;
163
- border-radius: 50%;
167
+ border-radius: 13px;
164
168
  text-align: center;
165
169
  line-height: 26px;
166
170
  font-size: 14px;
167
- letter-spacing: -1px;
171
+ letter-spacing: -0.5px;
172
+ padding: 0 5px;
168
173
  }
169
174
 
170
175
  .route-color-swatch-large {
171
- width: 40px;
176
+ min-width: 40px;
172
177
  height: 40px;
173
- border-radius: 50%;
178
+ border-radius: 20px;
174
179
  text-align: center;
175
180
  line-height: 40px;
176
181
  font-size: 20px;
177
182
  font-weight: bold;
178
183
  letter-spacing: -1px;
184
+ padding: 0 8px;
179
185
  }
180
186
 
181
187
  @media screen and (max-width: 767px) {
@@ -187,45 +193,45 @@ a:hover {
187
193
  border: 1px solid #ddd;
188
194
  }
189
195
 
190
- .table-responsive>table {
196
+ .table-responsive > table {
191
197
  margin-bottom: 0;
192
198
  }
193
199
 
194
- .table-responsive>table>thead>tr>th,
195
- .table-responsive>table>tbody>tr>th,
196
- .table-responsive>table>tfoot>tr>th,
197
- .table-responsive>table>thead>tr>td,
198
- .table-responsive>table>tbody>tr>td,
199
- .table-responsive>table>tfoot>tr>td {
200
+ .table-responsive > table > thead > tr > th,
201
+ .table-responsive > table > tbody > tr > th,
202
+ .table-responsive > table > tfoot > tr > th,
203
+ .table-responsive > table > thead > tr > td,
204
+ .table-responsive > table > tbody > tr > td,
205
+ .table-responsive > table > tfoot > tr > td {
200
206
  white-space: nowrap;
201
207
  }
202
208
 
203
- .table-responsive>.table-bordered {
209
+ .table-responsive > .table-bordered {
204
210
  border: 0;
205
211
  }
206
212
 
207
- .table-responsive>.table-bordered>thead>tr>th:first-child,
208
- .table-responsive>.table-bordered>tbody>tr>th:first-child,
209
- .table-responsive>.table-bordered>tfoot>tr>th:first-child,
210
- .table-responsive>.table-bordered>thead>tr>td:first-child,
211
- .table-responsive>.table-bordered>tbody>tr>td:first-child,
212
- .table-responsive>.table-bordered>tfoot>tr>td:first-child {
213
+ .table-responsive > .table-bordered > thead > tr > th:first-child,
214
+ .table-responsive > .table-bordered > tbody > tr > th:first-child,
215
+ .table-responsive > .table-bordered > tfoot > tr > th:first-child,
216
+ .table-responsive > .table-bordered > thead > tr > td:first-child,
217
+ .table-responsive > .table-bordered > tbody > tr > td:first-child,
218
+ .table-responsive > .table-bordered > tfoot > tr > td:first-child {
213
219
  border-left: 0;
214
220
  }
215
221
 
216
- .table-responsive>.table-bordered>thead>tr>th:last-child,
217
- .table-responsive>.table-bordered>tbody>tr>th:last-child,
218
- .table-responsive>.table-bordered>tfoot>tr>th:last-child,
219
- .table-responsive>.table-bordered>thead>tr>td:last-child,
220
- .table-responsive>.table-bordered>tbody>tr>td:last-child,
221
- .table-responsive>.table-bordered>tfoot>tr>td:last-child {
222
+ .table-responsive > .table-bordered > thead > tr > th:last-child,
223
+ .table-responsive > .table-bordered > tbody > tr > th:last-child,
224
+ .table-responsive > .table-bordered > tfoot > tr > th:last-child,
225
+ .table-responsive > .table-bordered > thead > tr > td:last-child,
226
+ .table-responsive > .table-bordered > tbody > tr > td:last-child,
227
+ .table-responsive > .table-bordered > tfoot > tr > td:last-child {
222
228
  border-right: 0;
223
229
  }
224
230
 
225
- .table-responsive>.table-bordered>tbody>tr:last-child>th,
226
- .table-responsive>.table-bordered>tfoot>tr:last-child>th,
227
- .table-responsive>.table-bordered>tbody>tr:last-child>td,
228
- .table-responsive>.table-bordered>tfoot>tr:last-child>td {
231
+ .table-responsive > .table-bordered > tbody > tr:last-child > th,
232
+ .table-responsive > .table-bordered > tfoot > tr:last-child > th,
233
+ .table-responsive > .table-bordered > tbody > tr:last-child > td,
234
+ .table-responsive > .table-bordered > tfoot > tr:last-child > td {
229
235
  border-bottom: 0;
230
236
  }
231
237
 
@@ -4,7 +4,9 @@
4
4
  const maps = {};
5
5
 
6
6
  function formatRoute(route) {
7
- const html = route.route_url ? $('<a>').attr('href', route.route_url) : $('<div>');
7
+ const html = route.route_url
8
+ ? $('<a>').attr('href', route.route_url)
9
+ : $('<div>');
8
10
 
9
11
  html.addClass('route-item text-sm mb-2');
10
12
 
@@ -26,13 +28,10 @@ function formatRoutePopup(features) {
26
28
  const html = $('<div>');
27
29
 
28
30
  if (features.length > 1) {
29
- $('<div>')
30
- .addClass('popup-title')
31
- .text('Routes')
32
- .appendTo(html);
31
+ $('<div>').addClass('popup-title').text('Routes').appendTo(html);
33
32
  }
34
33
 
35
- $(html).append(features.map(feature => formatRoute(feature.properties)));
34
+ $(html).append(features.map((feature) => formatRoute(feature.properties)));
36
35
 
37
36
  return html.prop('outerHTML');
38
37
  }
@@ -67,7 +66,7 @@ function createSystemMap(id, geojson) {
67
66
  container: id,
68
67
  style: 'mapbox://styles/mapbox/light-v10',
69
68
  center: bounds.getCenter(),
70
- zoom: 12
69
+ zoom: 12,
71
70
  });
72
71
  const routes = {};
73
72
 
@@ -81,7 +80,7 @@ function createSystemMap(id, geojson) {
81
80
  map.on('load', () => {
82
81
  map.fitBounds(bounds, {
83
82
  padding: 20,
84
- duration: 0
83
+ duration: 0,
85
84
  });
86
85
 
87
86
  // Find the index of the first symbol layer in the map style
@@ -96,71 +95,79 @@ function createSystemMap(id, geojson) {
96
95
  // Add white outlines to routes first
97
96
  for (const routeId of Object.keys(routes)) {
98
97
  routeBackgroundLayerIds.push(`${routeId}outline`);
99
- map.addLayer({
100
- id: `${routeId}outline`,
101
- type: 'line',
102
- source: {
103
- type: 'geojson',
104
- data: geojson
105
- },
106
- paint: {
107
- 'line-color': '#FFFFFF',
108
- 'line-opacity': 1,
109
- 'line-width': 6
98
+ map.addLayer(
99
+ {
100
+ id: `${routeId}outline`,
101
+ type: 'line',
102
+ source: {
103
+ type: 'geojson',
104
+ data: geojson,
105
+ },
106
+ paint: {
107
+ 'line-color': '#FFFFFF',
108
+ 'line-opacity': 1,
109
+ 'line-width': 6,
110
+ },
111
+ layout: {
112
+ 'line-join': 'round',
113
+ 'line-cap': 'round',
114
+ },
115
+ filter: ['==', 'route_id', routeId],
110
116
  },
111
- layout: {
112
- 'line-join': 'round',
113
- 'line-cap': 'round'
114
- },
115
- filter: ['==', 'route_id', routeId]
116
- }, firstSymbolId);
117
+ firstSymbolId
118
+ );
117
119
  }
118
120
 
119
121
  // Add route lines next
120
122
  for (const routeId of Object.keys(routes)) {
121
123
  routeLayerIds.push(routeId);
122
124
  const routeColor = routes[routeId].route_color || defaultRouteColor;
123
- map.addLayer({
124
- id: routeId,
125
- type: 'line',
126
- source: {
127
- type: 'geojson',
128
- data: geojson
125
+ map.addLayer(
126
+ {
127
+ id: routeId,
128
+ type: 'line',
129
+ source: {
130
+ type: 'geojson',
131
+ data: geojson,
132
+ },
133
+ paint: {
134
+ 'line-color': routeColor,
135
+ 'line-opacity': 1,
136
+ 'line-width': 2,
137
+ },
138
+ layout: {
139
+ 'line-join': 'round',
140
+ 'line-cap': 'round',
141
+ },
142
+ filter: ['==', 'route_id', routeId],
129
143
  },
130
- paint: {
131
- 'line-color': routeColor,
132
- 'line-opacity': 1,
133
- 'line-width': 2
134
- },
135
- layout: {
136
- 'line-join': 'round',
137
- 'line-cap': 'round'
138
- },
139
- filter: ['==', 'route_id', routeId]
140
- }, firstSymbolId);
144
+ firstSymbolId
145
+ );
141
146
  }
142
147
 
143
- map.on('mousemove', event => {
148
+ map.on('mousemove', (event) => {
144
149
  const features = map.queryRenderedFeatures(event.point, {
145
- layers: [...routeLayerIds, ...routeBackgroundLayerIds]
150
+ layers: [...routeLayerIds, ...routeBackgroundLayerIds],
146
151
  });
147
152
  if (features.length > 0) {
148
153
  map.getCanvas().style.cursor = 'pointer';
149
- highlightRoutes(_.uniq(features.map(feature => feature.properties.route_id)));
154
+ highlightRoutes(
155
+ _.uniq(features.map((feature) => feature.properties.route_id))
156
+ );
150
157
  } else {
151
158
  map.getCanvas().style.cursor = '';
152
159
  unHighlightRoutes();
153
160
  }
154
161
  });
155
162
 
156
- map.on('click', event => {
163
+ map.on('click', (event) => {
157
164
  // Set bbox as 5px reactangle area around clicked point
158
165
  const bbox = [
159
166
  [event.point.x - 5, event.point.y - 5],
160
- [event.point.x + 5, event.point.y + 5]
167
+ [event.point.x + 5, event.point.y + 5],
161
168
  ];
162
169
  const features = map.queryRenderedFeatures(bbox, {
163
- layers: routeLayerIds
170
+ layers: routeLayerIds,
164
171
  });
165
172
 
166
173
  if (!features || features.length === 0) {
@@ -168,11 +175,8 @@ function createSystemMap(id, geojson) {
168
175
  }
169
176
 
170
177
  const routeFeatures = _.orderBy(
171
- _.uniqBy(
172
- features,
173
- feature => feature.properties.route_short_name
174
- ),
175
- feature => Number.parseInt(feature.properties.route_short_name, 10)
178
+ _.uniqBy(features, (feature) => feature.properties.route_short_name),
179
+ (feature) => Number.parseInt(feature.properties.route_short_name, 10)
176
180
  );
177
181
 
178
182
  new mapboxgl.Popup()
@@ -183,13 +187,19 @@ function createSystemMap(id, geojson) {
183
187
 
184
188
  function highlightRoutes(routeIds, zoom) {
185
189
  for (const layerId of routeBackgroundLayerIds) {
186
- const color = routeIds.includes(layerId.replace(/outline/, '')) ? '#FFFD7E' : '#FFFFFF';
187
- const width = routeIds.includes(layerId.replace(/outline/, '')) ? 12 : 6;
190
+ const color = routeIds.includes(layerId.replace(/outline/, ''))
191
+ ? '#FFFD7E'
192
+ : '#FFFFFF';
193
+ const width = routeIds.includes(layerId.replace(/outline/, ''))
194
+ ? 12
195
+ : 6;
188
196
  map.setPaintProperty(layerId, 'line-color', color);
189
197
  map.setPaintProperty(layerId, 'line-width', width);
190
198
  }
191
199
 
192
- const highlightedFeatures = geojson.features.filter(feature => routeIds.includes(feature.properties.route_id));
200
+ const highlightedFeatures = geojson.features.filter((feature) =>
201
+ routeIds.includes(feature.properties.route_id)
202
+ );
193
203
 
194
204
  if (highlightedFeatures.length === 0) {
195
205
  return;
@@ -197,10 +207,10 @@ function createSystemMap(id, geojson) {
197
207
 
198
208
  if (zoom) {
199
209
  const zoomBounds = getBounds({
200
- features: highlightedFeatures
210
+ features: highlightedFeatures,
201
211
  });
202
212
  map.fitBounds(zoomBounds, {
203
- padding: 20
213
+ padding: 20,
204
214
  });
205
215
  }
206
216
  }
@@ -218,7 +228,7 @@ function createSystemMap(id, geojson) {
218
228
 
219
229
  // On table hover, highlight route on map
220
230
  $(() => {
221
- $('.overview-list a').hover(event => {
231
+ $('.overview-list a').hover((event) => {
222
232
  const routeIdString = $(event.target).parents('a').data('route-ids');
223
233
  if (routeIdString) {
224
234
  const routeIds = routeIdString.toString().split(',');
@@ -226,7 +236,10 @@ function createSystemMap(id, geojson) {
226
236
  }
227
237
  });
228
238
 
229
- $('.overview-list').hover(() => {}, () => unHighlightRoutes(true));
239
+ $('.overview-list').hover(
240
+ () => {},
241
+ () => unHighlightRoutes(true)
242
+ );
230
243
  });
231
244
  });
232
245