bare-script 3.5.1 → 3.5.3

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.
@@ -95,38 +95,61 @@ endfunction
95
95
  # $arg options: - **hideMenu** - Hide the menu links
96
96
  # $arg options: - **hideNav** - Hide the navigation links
97
97
  # $arg options: - **start** - The start page name
98
+ # $arg options: - **keyboard** - Enable keyboard commands ('n' for next, 'p' for previous, 's' for start, 'e' for end)
98
99
  async function pagerMain(pagerModel, options):
99
- if options == null:
100
- options = objectNew()
101
- endif
100
+ options = if(options != null, options, objectNew())
101
+ optionArguments = objectGet(options, 'arguments')
102
+ optionHideMenu = objectGet(options, 'hideMenu')
103
+ optionHideNav = objectGet(options, 'hideNav')
104
+ optionStart = objectGet(options, 'start')
105
+ optionKeyboard = objectGet(options, 'keyboard')
102
106
 
103
107
  # Validate the pager model
104
108
  pagerModel = pagerValidate(pagerModel)
105
109
  if pagerModel == null:
106
110
  return
107
111
  endif
108
-
109
- # Compute the visible and navigable pages
110
112
  pages = objectGet(pagerModel, 'pages')
111
- visiblePages = arrayNew()
112
- navPages = arrayNew()
113
- for page in pages:
114
- # Visible page?
115
- if !objectGet(page, 'hidden'):
116
- arrayPush(visiblePages, page)
117
-
118
- # Navigable page?
119
- pageTypeKey = arrayGet(objectKeys(objectGet(page, 'type')), 0)
120
- if pageTypeKey != 'link':
121
- arrayPush(navPages, page)
122
- endif
113
+ pagesLength = arrayLength(pages)
114
+
115
+ # Find the start page and end page
116
+ startPageName = null
117
+ startPageIndex = null
118
+ startPageExplicit = null
119
+ endPageName = null
120
+ for page, ixPage in pages:
121
+ pageName = objectGet(page, 'name')
122
+ pageHidden = objectGet(page, 'hidden')
123
+ pageTypeKey = arrayGet(objectKeys(objectGet(page, 'type')), 0)
124
+ pageNavigable = pageTypeKey != 'link'
125
+
126
+ # Start page?
127
+ if pageNavigable && !pageHidden && startPageName == null:
128
+ startPageName = pageName
129
+ startPageIndex = ixPage
130
+ elif !startPageExplicit && pageName == optionStart:
131
+ startPageName = pageName
132
+ startPageIndex = ixPage
133
+ startPageExplicit = true
134
+ endif
135
+
136
+ # Update the end page
137
+ if pageNavigable && !pageHidden:
138
+ endPageName = pageName
123
139
  endif
124
140
  endfor
141
+ if startPageName == null:
142
+ systemLogDebug('MarkdownUp - pager.bare: No visible and navigable pages')
143
+ return
144
+ endif
145
+ if optionStart && !startPageExplicit:
146
+ systemLogDebug('MarkdownUp - pager.bare: Unknown start page "' + optionStart + '"')
147
+ return
148
+ endif
125
149
 
126
150
  # Parse arguments
127
- startPageName = objectGet(options, 'start', if(arrayLength(navPages), objectGet(arrayGet(navPages, 0), 'name'), null))
128
- if objectHas(options, 'arguments'):
129
- arguments = argsValidate(objectGet(options, 'arguments'))
151
+ if optionArguments:
152
+ arguments = argsValidate(optionArguments)
130
153
  if arguments == null:
131
154
  return
132
155
  endif
@@ -134,70 +157,96 @@ async function pagerMain(pagerModel, options):
134
157
  arguments = arrayNew(objectNew('name', 'page', 'default', startPageName))
135
158
  endif
136
159
  args = argsParse(arguments)
160
+ argPage = objectGet(args, 'page')
161
+
162
+ # Find the current page
163
+ curPage = arrayGet(pages, startPageIndex)
164
+ curPageName = startPageName
165
+ curPageIndex = startPageIndex
166
+ for page, ixPage in pages:
167
+ pageName = objectGet(page, 'name')
168
+ pageTypeKey = arrayGet(objectKeys(objectGet(page, 'type')), 0)
169
+ pageNavigable = pageTypeKey != 'link'
137
170
 
138
- # Determine the current page
139
- curPage = null
140
- startPage = null
141
- for page in pages:
142
- if objectGet(page, 'name') == objectGet(args, 'page'):
171
+ # Current page?
172
+ if pageNavigable && pageName == argPage:
143
173
  curPage = page
144
- endif
145
- if objectGet(page, 'name') == startPageName:
146
- startPage = page
174
+ curPageName = pageName
175
+ curPageIndex = ixPage
176
+ break
147
177
  endif
148
178
  endfor
149
- if startPage == null:
150
- systemLogDebug('MarkdownUp - pager.bare: Unknown start page' + if(startPageName != null, '"' + startPageName + '"', ''))
151
- return
152
- endif
153
- if curPage == null:
154
- curPage = startPage
155
- endif
156
179
 
157
- # Determine the current page's navigable index, if any
158
- ixCurPage = -1
159
- for navPage, ixNavPage in navPages:
160
- if objectGet(navPage, 'name') == objectGet(curPage, 'name'):
161
- ixCurPage = ixNavPage
180
+ # Find the next page
181
+ nextPageName = null
182
+ ixPage = curPageIndex + 1
183
+ while ixPage < pagesLength:
184
+ page = arrayGet(pages, ixPage)
185
+ pageName = objectGet(page, 'name')
186
+ pageHidden = objectGet(page, 'hidden')
187
+ pageTypeKey = arrayGet(objectKeys(objectGet(page, 'type')), 0)
188
+ pageNavigable = pageTypeKey != 'link'
189
+ if !pageHidden && pageNavigable:
190
+ nextPageName = pageName
162
191
  break
163
192
  endif
164
- endfor
193
+ ixPage = ixPage + 1
194
+ endwhile
195
+
196
+ # Find the previous page
197
+ prevPageName = null
198
+ ixPage = curPageIndex - 1
199
+ while ixPage >= 0:
200
+ page = arrayGet(pages, ixPage)
201
+ pageName = objectGet(page, 'name')
202
+ pageHidden = objectGet(page, 'hidden')
203
+ pageTypeKey = arrayGet(objectKeys(objectGet(page, 'type')), 0)
204
+ pageNavigable = pageTypeKey != 'link'
205
+ if !pageHidden && pageNavigable:
206
+ prevPageName = pageName
207
+ break
208
+ endif
209
+ ixPage = ixPage - 1
210
+ endwhile
165
211
 
166
212
  # Render the menu
167
- if !objectGet(options, 'hideMenu'):
168
- for page, ixPage in visiblePages:
213
+ if !optionHideMenu:
214
+ menuItems = arrayNew()
215
+ for page in pages:
169
216
  pageName = objectGet(page, 'name')
217
+ pageHidden = objectGet(page, 'hidden')
170
218
  pageType = objectGet(page, 'type')
171
219
  pageTypeKey = arrayGet(objectKeys(pageType), 0)
220
+ pageNavigable = pageTypeKey != 'link'
221
+
222
+ # Hidden page?
223
+ if pageHidden:
224
+ continue
225
+ endif
172
226
 
173
227
  # Render the menu link
174
- pageNameNbsp = stringReplace(pageName, ' ', '&nbsp;')
175
- separator = if(ixPage != arrayLength(visiblePages) - 1, '&nbsp;|', '')
176
228
  if pageTypeKey == 'link':
177
229
  pageLinkURL = objectGet(objectGet(pageType, 'link'), 'url')
178
- markdownPrint('[' + markdownEscape(pageNameNbsp) + '](' + urlEncode(pageLinkURL) + ')' + separator)
230
+ arrayPush(menuItems, '[' + markdownEscape(pageName) + '](' + urlEncode(pageLinkURL) + ')')
179
231
  elif pageName == objectGet(curPage, 'name'):
180
- markdownPrint(markdownEscape(pageNameNbsp) + separator)
232
+ arrayPush(menuItems, markdownEscape(pageName))
181
233
  else:
182
- markdownPrint(argsLink(arguments, pageNameNbsp, objectNew('page', pageName)) + separator)
234
+ arrayPush(menuItems, argsLink(arguments, pageName, objectNew('page', pageName)))
183
235
  endif
184
236
  endfor
185
- markdownPrint('')
237
+ markdownPrint(arrayJoin(menuItems, '&nbsp;|&nbsp;'), '')
186
238
  endif
187
239
 
188
240
  # Render the start/next/prev buttons
189
- if !objectGet(options, 'hideNav') && arrayLength(navPages) > 1 && ixCurPage != -1:
190
- if startPageName == objectGet(curPage, 'name'):
191
- startPageName = null
192
- endif
193
- prevPageName = if(ixCurPage != -1 && ixCurPage - 1 >= 0, objectGet(arrayGet(navPages, ixCurPage - 1), 'name'), null)
194
- nextPageName = if(ixCurPage != -1 && ixCurPage + 1 < arrayLength(navPages), objectGet(arrayGet(navPages, ixCurPage + 1), 'name'), null)
195
- markdownPrint( \
196
- '(&nbsp;' + if(startPageName != null, argsLink(arguments, 'Start', objectNew('page', startPageName)), 'Start') + '&nbsp;|', \
197
- if(prevPageName != null, argsLink(arguments, 'Previous', objectNew('page', prevPageName)), 'Previous') + '&nbsp;|', \
198
- if(nextPageName != null, argsLink(arguments, 'Next', objectNew('page', nextPageName)), 'Next') + '&nbsp;)', \
199
- '' \
200
- )
241
+ if !optionHideNav && (nextPageName != null || prevPageName != null):
242
+ navItems = arrayNew()
243
+ arrayPush(navItems, \
244
+ if(startPageName != curPageName, argsLink(arguments, 'Start', objectNew('page', startPageName)), 'Start'))
245
+ arrayPush(navItems, \
246
+ if(prevPageName != null, argsLink(arguments, 'Previous', objectNew('page', prevPageName)), 'Previous'))
247
+ arrayPush(navItems, \
248
+ if(nextPageName != null, argsLink(arguments, 'Next', objectNew('page', nextPageName)), 'Next'))
249
+ markdownPrint('(&nbsp;' + arrayJoin(navItems, '&nbsp;|&nbsp;') + '&nbsp;)', '')
201
250
  endif
202
251
 
203
252
  # Function page?
@@ -233,4 +282,27 @@ async function pagerMain(pagerModel, options):
233
282
  markdownPrint('', markdownText)
234
283
  endif
235
284
  endif
285
+
286
+ # Set the keydown handler
287
+ if optionKeyboard:
288
+ documentSetKeyDown(systemPartial(pagerKeyDown, arguments, curPageName, startPageName, endPageName, nextPageName, prevPageName))
289
+ endif
290
+ endfunction
291
+
292
+
293
+ function pagerKeyDown(arguments, curPageName, startPageName, endPageName, nextPageName, prevPageName, event):
294
+ key = objectGet(event, 'key')
295
+ if key == 's' && startPageName != curPageName:
296
+ # Start slide
297
+ windowSetLocation(argsURL(arguments, objectNew('page', startPageName)))
298
+ elif key == 'e' && endPageName != curPageName:
299
+ # End slide
300
+ windowSetLocation(argsURL(arguments, objectNew('page', endPageName)))
301
+ elif key == 'n' && nextPageName:
302
+ # Next page
303
+ windowSetLocation(argsURL(arguments, objectNew('page', nextPageName)))
304
+ elif key == 'p' && prevPageName:
305
+ # Previous page
306
+ windowSetLocation(argsURL(arguments, objectNew('page', prevPageName)))
307
+ endif
236
308
  endfunction
package/lib/parser.js CHANGED
@@ -450,27 +450,30 @@ const rScriptLineSplit = /\r?\n/;
450
450
  const rScriptContinuation = /\\\s*$/;
451
451
  const rScriptComment = /^\s*(?:#.*)?$/;
452
452
  const rScriptAssignment = /^\s*(?<name>[A-Za-z_]\w*)\s*=\s*(?<expr>.+)$/;
453
+ const rPartComment = '\\s*(#.*)?$';
453
454
  const rScriptFunctionBegin = new RegExp(
454
455
  '^(?<async>\\s*async)?\\s*function\\s+(?<name>[A-Za-z_]\\w*)\\s*\\(' +
455
- '\\s*(?<args>[A-Za-z_]\\w*(?:\\s*,\\s*[A-Za-z_]\\w*)*)?(?<lastArgArray>\\s*\\.\\.\\.)?\\s*\\)\\s*:\\s*$'
456
+ `\\s*(?<args>[A-Za-z_]\\w*(?:\\s*,\\s*[A-Za-z_]\\w*)*)?(?<lastArgArray>\\s*\\.\\.\\.)?\\s*\\)\\s*:${rPartComment}`
456
457
  );
457
458
  const rScriptFunctionArgSplit = /\s*,\s*/;
458
- const rScriptFunctionEnd = /^\s*endfunction\s*$/;
459
- const rScriptLabel = /^\s*(?<name>[A-Za-z_]\w*)\s*:\s*$/;
460
- const rScriptJump = /^(?<jump>\s*(?:jump|jumpif\s*\((?<expr>.+)\)))\s+(?<name>[A-Za-z_]\w*)\s*$/;
461
- const rScriptReturn = /^(?<return>\s*return(?:\s+(?<expr>.+))?)\s*$/;
462
- const rScriptInclude = /^\s*include\s+(?<delim>')(?<url>(?:\\'|[^'])*)'\s*$/;
463
- const rScriptIncludeSystem = /^\s*include\s+(?<delim><)(?<url>[^>]*)>\s*$/;
464
- const rScriptIfBegin = /^\s*if\s+(?<expr>.+)\s*:\s*$/;
465
- const rScriptIfElseIf = /^\s*elif\s+(?<expr>.+)\s*:\s*$/;
466
- const rScriptIfElse = /^\s*else\s*:\s*$/;
467
- const rScriptIfEnd = /^\s*endif\s*$/;
468
- const rScriptForBegin = /^\s*for\s+(?<value>[A-Za-z_]\w*)(?:\s*,\s*(?<index>[A-Za-z_]\w*))?\s+in\s+(?<values>.+)\s*:\s*$/;
469
- const rScriptForEnd = /^\s*endfor\s*$/;
470
- const rScriptWhileBegin = /^\s*while\s+(?<expr>.+)\s*:\s*$/;
471
- const rScriptWhileEnd = /^\s*endwhile\s*$/;
472
- const rScriptBreak = /^\s*break\s*$/;
473
- const rScriptContinue = /^\s*continue\s*$/;
459
+ const rScriptFunctionEnd = new RegExp(`^\\s*endfunction${rPartComment}`);
460
+ const rScriptLabel = new RegExp(`^\\s*(?<name>[A-Za-z_]\\w*)\\s*:${rPartComment}`);
461
+ const rScriptJump = new RegExp(`^(?<jump>\\s*(?:jump|jumpif\\s*\\((?<expr>.+)\\)))\\s+(?<name>[A-Za-z_]\\w*)${rPartComment}`);
462
+ const rScriptReturn = new RegExp(`^(?<return>\\s*return(?:\\s+(?<expr>.+))?)${rPartComment}`);
463
+ const rScriptInclude = new RegExp(`^\\s*include\\s+(?<delim>')(?<url>(?:\\'|[^'])*)'${rPartComment}`);
464
+ const rScriptIncludeSystem = new RegExp(`^\\s*include\\s+(?<delim><)(?<url>[^>]*)>${rPartComment}`);
465
+ const rScriptIfBegin = new RegExp(`^\\s*if\\s+(?<expr>.+)\\s*:${rPartComment}`);
466
+ const rScriptIfElseIf = new RegExp(`^\\s*elif\\s+(?<expr>.+)\\s*:${rPartComment}`);
467
+ const rScriptIfElse = new RegExp(`^\\s*else\\s*:${rPartComment}`);
468
+ const rScriptIfEnd = new RegExp(`^\\s*endif${rPartComment}`);
469
+ const rScriptForBegin = new RegExp(
470
+ `^\\s*for\\s+(?<value>[A-Za-z_]\\w*)(?:\\s*,\\s*(?<index>[A-Za-z_]\\w*))?\\s+in\\s+(?<values>.+)\\s*:${rPartComment}`
471
+ );
472
+ const rScriptForEnd = new RegExp(`^\\s*endfor${rPartComment}`);
473
+ const rScriptWhileBegin = new RegExp(`^\\s*while\\s+(?<expr>.+)\\s*:${rPartComment}`);
474
+ const rScriptWhileEnd = new RegExp(`^\\s*endwhile${rPartComment}`);
475
+ const rScriptBreak = new RegExp(`^\\s*break${rPartComment}`);
476
+ const rScriptContinue = new RegExp(`^\\s*continue${rPartComment}`);
474
477
 
475
478
 
476
479
  /**
@@ -509,6 +512,11 @@ function parseBinaryExpression(exprText, binLeftExpr = null) {
509
512
  // Match a binary operator - if not found, return the left expression
510
513
  const matchBinaryOp = binText.match(rExprBinaryOp);
511
514
  if (matchBinaryOp === null) {
515
+ // End-of-line comment?
516
+ if (binText.match(rExprComment)) {
517
+ binText = '';
518
+ }
519
+
512
520
  return [leftExpr, binText];
513
521
  }
514
522
  const [, binOp] = matchBinaryOp;
@@ -671,6 +679,7 @@ function parseUnaryExpression(exprText) {
671
679
 
672
680
 
673
681
  // BareScript expression regex
682
+ const rExprComment = /^\s*#.*$/;
674
683
  const rExprBinaryOp = /^\s*(\*\*|\*|\/|%|\+|-|<<|>>|<=|<|>=|>|==|!=|&&|\|\||&|\^|\|)/;
675
684
  const rExprUnaryOp = /^\s*(!|-|~)/;
676
685
  const rExprFunctionOpen = /^\s*([A-Za-z_]\w+)\s*\(/;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "bare-script",
4
- "version": "3.5.1",
4
+ "version": "3.5.3",
5
5
  "description": "BareScript; a lightweight scripting and expression language",
6
6
  "keywords": [
7
7
  "expression",