|
22 | 22 | (contract-out |
23 | 23 | [read-markdown (->* () (symbol?) xexpr-element-list?)] |
24 | 24 | [parse-markdown (->* ((or/c string? path?)) (symbol?) xexpr-element-list?)] |
25 | | - [current-strict-markdown? parameter/c])) |
| 25 | + [current-strict-markdown? (parameter/c boolean?)] |
| 26 | + [current-entity-handler (parameter/c entity-handler/c)] |
| 27 | + [default-entity-handler entity-handler/c] |
| 28 | + [scribble-entity-handler entity-handler/c])) |
26 | 29 |
|
27 | 30 | (module+ test |
28 | 31 | (require rackunit)) |
29 | 32 |
|
30 | 33 | (define (xexpr-element-list? xs) |
31 | 34 | (xexpr? `(dummy () ,@xs))) |
32 | 35 |
|
| 36 | +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 37 | +;; Entity handler |
| 38 | + |
| 39 | +;; Given an original xexpr and a proposed symbol entity substitution, |
| 40 | +;; an entity-handler returns which to use. |
| 41 | +(define entity-handler/c (-> xexpr/c symbol? xexpr/c)) |
| 42 | + |
| 43 | +;; A default entity-handler that accepts every proposed substitution. |
| 44 | +(define (default-entity-handler _ sym) |
| 45 | + sym) |
| 46 | + |
| 47 | +;; An entity-handler suitable for use to produce x-expressions that |
| 48 | +;; you want to give to scribble, which expects only a limited list. |
| 49 | +(define (scribble-entity-handler orig sym) |
| 50 | + (match sym |
| 51 | + [(or 'mdash 'ndash 'ldquo 'lsquo 'rdquo 'rsquo 'larr 'rarr 'prime) sym] |
| 52 | + [_ orig])) |
| 53 | + |
| 54 | +(define current-entity-handler (make-parameter default-entity-handler)) |
| 55 | + |
| 56 | +;; Alias for using the preceding, as we'll be using it frequently: |
| 57 | +(define (ent orig sym) |
| 58 | + ((current-entity-handler) orig sym)) |
| 59 | + |
33 | 60 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
34 | 61 | ;; General purpose combinators |
35 | 62 | ;; |
|
302 | 329 |
|
303 | 330 | (define $smart-em-dash |
304 | 331 | (>> (try (pdo (char #\-) (char #\-) (optional (char #\-)))) |
305 | | - (return 'mdash))) |
| 332 | + (return (ent "--" 'mdash)))) |
306 | 333 |
|
307 | 334 | (define $smart-en-dash |
308 | 335 | (try (pdo (char #\-) |
309 | 336 | (lookAhead (pdo (many (char #\space)) $digit)) |
310 | | - (return 'ndash)))) |
| 337 | + (return (ent "-" 'ndash))))) |
311 | 338 |
|
312 | 339 | (define $smart-dashes (<or> $smart-em-dash $smart-en-dash)) |
313 | 340 |
|
|
322 | 349 | last-$str-val |
323 | 350 | (for/and ([c (in-string last-$str-val)]) |
324 | 351 | (char-numeric? c))) |
325 | | - (return 'prime)] |
| 352 | + (return (ent "'" 'prime))] |
326 | 353 | [else (fail "")])))) |
327 | 354 |
|
328 | 355 | (define $smart-apostrophe |
329 | 356 | (pdo (char #\') |
330 | | - (return 'rsquo))) ;; could use 'apos for HTML5? |
| 357 | + (return (ent "'" 'rsquo)))) ;; could use 'apos for HTML5? |
331 | 358 |
|
332 | 359 | (define (fail-in-quote-context x) |
333 | 360 | (pdo (qc <- (getState 'quote-context)) |
|
353 | 380 | (fail-just-after-str) |
354 | 381 | (char #\') |
355 | 382 | (lookAhead (<or> $alphaNum (char #\"))) |
356 | | - (return 'sdquo))) |
| 383 | + (return #\'))) |
357 | 384 |
|
358 | 385 | (define $single-quote-end |
359 | 386 | (try (>> (char #\') |
|
363 | 390 | (try (pdo $single-quote-start |
364 | 391 | (xs <- (withState (['quote-context 'single]) |
365 | 392 | (many1Till $inline $single-quote-end))) |
366 | | - (return `(SPLICE lsquo ,@xs rsquo))))) |
| 393 | + (return `(SPLICE ,(ent "'" 'lsquo) ,@xs ,(ent "'" 'rsquo)))))) |
367 | 394 |
|
368 | 395 | (define $double-quote-start |
369 | 396 | (pdo (fail-in-quote-context 'double) |
370 | 397 | (fail-just-after-str) |
371 | 398 | (char #\") |
372 | 399 | (lookAhead (<or> $alphaNum (char #\'))) |
373 | | - (return 'ldquo))) |
| 400 | + (return #\"))) |
374 | 401 |
|
375 | 402 | (define $double-quote-end |
376 | 403 | (try (>> (char #\") |
|
380 | 407 | (try (pdo $double-quote-start |
381 | 408 | (xs <- (withState (['quote-context 'double]) |
382 | 409 | (many1Till $inline $double-quote-end))) |
383 | | - (return `(SPLICE ldquo ,@xs rdquo))))) |
| 410 | + (return `(SPLICE ,(ent "\"" 'ldquo) ,@xs ,(ent "\"" 'rdquo)))))) |
384 | 411 |
|
385 | 412 | (define $smart-quoted (<or> $smart-quoted/single |
386 | 413 | $smart-quoted/double)) |
387 | 414 |
|
388 | 415 | (define $smart-ellipses |
389 | | - (<?> (pdo (oneOfStrings "..." " . . . " ". . ." " . . .") |
390 | | - (return 'hellip)) |
| 416 | + (<?> (pdo (s <- (>>= (oneOfStrings "..." " . . . " ". . ." " . . .") |
| 417 | + (compose1 return list->string))) |
| 418 | + (return (ent s 'hellip))) |
391 | 419 | "ellipsis")) |
392 | 420 |
|
393 | 421 | (define $smart-punctuation |
|
0 commit comments