Support gitignore highlighting

Julien LepillerSun Jun 27 00:46:55+0200 2021

3bb7a30

Support gitignore highlighting

Makefile.am

1111
    gitile/handler.scm \
1212
    gitile/pages.scm \
1313
    gitile/repo.scm \
14-
	gitile/highlight/css.scm
14+
	gitile/highlight/utils.scm \
15+
	gitile/highlight/gitignore.scm
1516
1617
clean-go:
1718
	find . -name '*.go' -delete

assets/css/highlight.css

2626
  font-weight: bold;
2727
}
2828
29+
/* language-specific */
30+
31+
/***
32+
 * SCHEME *
33+
 *        ***/
34+
2935
.language-scheme .syntax-special {
3036
  color: var(--keyword);
3137
  font-weight: bold;

3844
.language-scheme .syntax-open, .language-scheme .syntax-close {
3945
  color: var(--comment);
4046
}
47+
48+
/***
49+
 * GITIGNORE *
50+
 *           ***/
51+
.language-gitignore .syntax-special {
52+
  color: var(--keyword);
53+
}

gitile/code.scm

2020
  #:use-module (ice-9 match)
2121
  #:use-module (syntax-highlight)
2222
  #:use-module (syntax-highlight scheme)
23-
  #:use-module (gitile highlight css)
23+
  #:use-module (gitile highlight gitignore)
24+
  #:use-module ((gitile highlight utils) #:prefix gitile:)
2425
  #:export (display-code
2526
            display-formatted-code))
2627

2829
  (let* ((extension (car (reverse (string-split (basename path) #\.))))
2930
         (language (match extension
3031
                     ("scm" "scheme")
31-
                     ("css" "css")
32+
                     ("gitignore" "gitignore")
3233
                     (_ "unknown"))))
3334
    `(table (@ (class ,(string-append "file-content language-" language)))
34-
       ,@(split-tr (highlights->sxml (highlight-code content language))))))
35+
       ,@(split-tr (gitile:highlights->sxml (highlight-code content language))))))
3536
3637
(define (display-formatted-code content language)
37-
  (highlights->sxml (highlight-code content language)))
38+
  (gitile:highlights->sxml (highlight-code content language)))
3839
3940
(define (highlight-code content language)
4041
  (match language
4142
    ("scheme" (highlight lex-scheme content))
42-
    ("css" (highlight lex-css content))
43+
    ("gitignore" (highlight lex-gitignore content))
4344
    (_ (list content))))
4445
4546
(define (split-lines content)
4647
  (let loop ((content content) (result '()) (line '()))
47-
    (match content
48+
    (match (pk 'split-lines-content content)
4849
      ((? string? s) (string-split s #\newline))
4950
      (() (append result (list line)))
5051
      (((? string? s) content ...)

7778
                   '()))))))))
7879
7980
(define (split-tr content)
81+
  (pk 'split-tr content)
8082
  (let loop ((result '()) (lines (split-lines content)) (line-num 1))
8183
    (match lines
8284
      (() result)

gitile/highlight/gitignore.scm unknown status 1

1+
(define-module (gitile highlight gitignore)
2+
  #:use-module (ice-9 match)
3+
  #:use-module (srfi srfi-1)
4+
  #:use-module (srfi srfi-11)
5+
  #:use-module (srfi srfi-26)
6+
  #:use-module (syntax-highlight lexers)
7+
  #:use-module (gitile highlight utils)
8+
  #:export (lex-gitignore))
9+
10+
(define lex-line
11+
  (lex-consume-until
12+
    (lex-string "\n")
13+
    (lex-any
14+
      (lex-tag 'special (apply lex-any (map lex-string '("*" "**" "?"))))
15+
      (lex-tag 'range (lex-delimited "[" #:until "]"))
16+
      (apply lex-any (map lex-string '("\\!" "\\*" "\\\\" "\\?")))
17+
      (lex-char-set (char-set-complement (char-set #\newline #\\ #\* #\?))))
18+
    #:tag 'line))
19+
20+
(define lex-gitignore
21+
  (lex-consume
22+
    (lex-any (lex-tag 'comment (lex-delimited "#" #:until "\n"))
23+
             (lex-tag 'special (lex-string "!"))
24+
             lex-line)))

gitile/highlight/utils.scm unknown status 1

1+
(define-module (gitile highlight utils)
2+
  #:use-module (ice-9 match)
3+
  #:use-module (srfi srfi-1)
4+
  #:use-module (srfi srfi-11)
5+
  #:use-module (syntax-highlight lexers)
6+
  #:export (highlights->sxml
7+
            lex-consume-until))
8+
9+
(define (flatten-highlights highlights)
10+
  (define (flatten-highlights-aux content tokens)
11+
    (pk 'content content 'tokens tokens)
12+
    (match content
13+
      ((? string? s) (if (null? tokens)
14+
                         s
15+
                         `((,@tokens ,s))))
16+
      (((? symbol? token) content ...)
17+
       (flatten-highlights-aux content (cons token tokens)))
18+
      ((? list? content)
19+
       (append-map (lambda (c) (flatten-highlights-aux c tokens)) content))))
20+
21+
  (pk 'content highlights)
22+
  (flatten-highlights-aux highlights '()))
23+
24+
(define (highlights->sxml highlights)
25+
  (define flat-highlights (flatten-highlights highlights))
26+
27+
  (define (tag->class tag)
28+
    (string-append "syntax-" (symbol->string tag)))
29+
30+
  (pk 'highlights flat-highlights)
31+
32+
  (map (match-lambda
33+
         ((? string? str) str)
34+
         ((content ...)
35+
          (let loop ((tags '()) (text "") (content content))
36+
            (match content
37+
             (() `(span (@ (class ,(string-join (map tag->class tags) " "))) ,text))
38+
             (((? symbol? tag) content ...)
39+
              (loop (cons tag tags) text content))
40+
             (((? string? s) content ...)
41+
              (loop tags (string-append text s) content))))))
42+
       flat-highlights))
43+
44+
(define* (lex-consume-until until lexer #:key (tag #f))
45+
  "Return a lexer that always succeeds with a list of as many consecutive
46+
successful applications of LEXER as possible, consuming the entire input text,
47+
or until a successful match of UNTIL, whichever comes first.  Sections of text
48+
that could not be lexed are returned as plain strings."
49+
  (define (substring* cursor start)
50+
    (substring (cursor-text cursor) start (cursor-position cursor)))
51+
52+
  (define (consume-until tokens cursor)
53+
    (if (cursor-end? cursor)
54+
        (values tokens cursor)
55+
        (let-values (((result remainder) (until tokens cursor)))
56+
          (if result
57+
              (values result remainder)
58+
              (let-values (((result remainder) (lexer tokens cursor)))
59+
                (if result
60+
                    (consume-until result remainder)
61+
                    (values (token-add tokens (cursor->string cursor))
62+
                            (move-cursor-to-end cursor))))))))
63+
64+
  (if tag
65+
      (lambda (tokens cursor)
66+
        (let-values (((result remainder) (consume-until empty-tokens cursor)))
67+
          (values (pk (token-add tokens (list tag (tokens->list result)))) remainder)))
68+
      consume-until))