Update golang versions everywhere, use alpine 3.13 for image, remove vendor dir.
This commit is contained in:
parent
a0f896dc53
commit
79791ef228
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
examples/fastpastebin.yaml
|
||||
dist/
|
||||
data/
|
||||
vendor/
|
||||
.idea
|
||||
.vscode
|
||||
*DS_Store*
|
||||
|
@ -1,13 +1,13 @@
|
||||
FROM golang:1.13.1-alpine AS build
|
||||
FROM golang:1.16.5-alpine AS build
|
||||
|
||||
WORKDIR /fastpastebin
|
||||
COPY . .
|
||||
|
||||
WORKDIR /fastpastebin/cmd/fastpastebin
|
||||
|
||||
RUN GOFLAGS="-mod=vendor" go build
|
||||
RUN CGO_ENABLED=0 go build -tags netgo
|
||||
|
||||
FROM alpine:3.10
|
||||
FROM alpine:3.13
|
||||
LABEL maintainer "Stanislav N. <pztrn@pztrn.name>"
|
||||
|
||||
COPY --from=build /fastpastebin/cmd/fastpastebin/fastpastebin /app/fastpastebin
|
||||
|
@ -5,7 +5,7 @@ volumes:
|
||||
|
||||
services:
|
||||
database:
|
||||
image: mariadb:10.3
|
||||
image: mariadb:10.5
|
||||
container_name: database
|
||||
restart: always
|
||||
volumes:
|
||||
|
2
go.mod
2
go.mod
@ -1,6 +1,6 @@
|
||||
module go.dev.pztrn.name/fastpastebin
|
||||
|
||||
go 1.13
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/alecthomas/chroma v0.8.2
|
||||
|
19
vendor/github.com/alecthomas/chroma/.gitignore
generated
vendored
19
vendor/github.com/alecthomas/chroma/.gitignore
generated
vendored
@ -1,19 +0,0 @@
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
/cmd/chroma/chroma
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
|
||||
.glide/
|
||||
|
||||
_models/
|
||||
|
||||
_examples/
|
55
vendor/github.com/alecthomas/chroma/.golangci.yml
generated
vendored
55
vendor/github.com/alecthomas/chroma/.golangci.yml
generated
vendored
@ -1,55 +0,0 @@
|
||||
run:
|
||||
tests: true
|
||||
skip-dirs:
|
||||
- _examples
|
||||
|
||||
output:
|
||||
print-issued-lines: false
|
||||
|
||||
linters:
|
||||
enable-all: true
|
||||
disable:
|
||||
- maligned
|
||||
- megacheck
|
||||
- lll
|
||||
- gocyclo
|
||||
- dupl
|
||||
- gochecknoglobals
|
||||
- funlen
|
||||
- godox
|
||||
- wsl
|
||||
- gomnd
|
||||
- gocognit
|
||||
|
||||
linters-settings:
|
||||
govet:
|
||||
check-shadowing: true
|
||||
gocyclo:
|
||||
min-complexity: 10
|
||||
dupl:
|
||||
threshold: 100
|
||||
goconst:
|
||||
min-len: 8
|
||||
min-occurrences: 3
|
||||
|
||||
issues:
|
||||
max-per-linter: 0
|
||||
max-same: 0
|
||||
exclude-use-default: false
|
||||
exclude:
|
||||
# Captured by errcheck.
|
||||
- '^(G104|G204):'
|
||||
# Very commonly not checked.
|
||||
- 'Error return value of .(.*\.Help|.*\.MarkFlagRequired|(os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked'
|
||||
- 'exported method (.*\.MarshalJSON|.*\.UnmarshalJSON|.*\.EntityURN|.*\.GoString|.*\.Pos) should have comment or be unexported'
|
||||
- 'composite literal uses unkeyed fields'
|
||||
- 'declaration of "err" shadows declaration'
|
||||
- 'should not use dot imports'
|
||||
- 'Potential file inclusion via variable'
|
||||
- 'should have comment or be unexported'
|
||||
- 'comment on exported var .* should be of the form'
|
||||
- 'at least one file in a package should have a package comment'
|
||||
- 'string literal contains the Unicode'
|
||||
- 'methods on the same type should have the same receiver name'
|
||||
- '_TokenType_name should be _TokenTypeName'
|
||||
- '`_TokenType_map` should be `_TokenTypeMap`'
|
33
vendor/github.com/alecthomas/chroma/.goreleaser.yml
generated
vendored
33
vendor/github.com/alecthomas/chroma/.goreleaser.yml
generated
vendored
@ -1,33 +0,0 @@
|
||||
project_name: chroma
|
||||
release:
|
||||
github:
|
||||
owner: alecthomas
|
||||
name: chroma
|
||||
brews:
|
||||
-
|
||||
install: bin.install "chroma"
|
||||
builds:
|
||||
- goos:
|
||||
- linux
|
||||
- darwin
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
- "386"
|
||||
goarm:
|
||||
- "6"
|
||||
main: ./cmd/chroma/main.go
|
||||
ldflags: -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}
|
||||
binary: chroma
|
||||
archives:
|
||||
-
|
||||
format: tar.gz
|
||||
name_template: '{{ .Binary }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{
|
||||
.Arm }}{{ end }}'
|
||||
files:
|
||||
- COPYING
|
||||
- README*
|
||||
snapshot:
|
||||
name_template: SNAPSHOT-{{ .Commit }}
|
||||
checksum:
|
||||
name_template: '{{ .ProjectName }}-{{ .Version }}-checksums.txt'
|
12
vendor/github.com/alecthomas/chroma/.travis.yml
generated
vendored
12
vendor/github.com/alecthomas/chroma/.travis.yml
generated
vendored
@ -1,12 +0,0 @@
|
||||
sudo: false
|
||||
language: go
|
||||
go:
|
||||
- "1.13.x"
|
||||
script:
|
||||
- go test -v ./...
|
||||
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s v1.22.2
|
||||
- ./bin/golangci-lint run
|
||||
- git clean -fdx .
|
||||
after_success:
|
||||
curl -sL https://git.io/goreleaser | bash && goreleaser
|
||||
|
19
vendor/github.com/alecthomas/chroma/COPYING
generated
vendored
19
vendor/github.com/alecthomas/chroma/COPYING
generated
vendored
@ -1,19 +0,0 @@
|
||||
Copyright (C) 2017 Alec Thomas
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
19
vendor/github.com/alecthomas/chroma/Makefile
generated
vendored
19
vendor/github.com/alecthomas/chroma/Makefile
generated
vendored
@ -1,19 +0,0 @@
|
||||
.PHONY: chromad upload all
|
||||
|
||||
all: README.md tokentype_string.go
|
||||
|
||||
README.md: lexers/*/*.go
|
||||
./table.py
|
||||
|
||||
tokentype_string.go: types.go
|
||||
go generate
|
||||
|
||||
chromad:
|
||||
(cd ./cmd/chromad && go get github.com/GeertJohan/go.rice/rice@master && go install github.com/GeertJohan/go.rice/rice)
|
||||
rm -f chromad
|
||||
(export CGOENABLED=0 GOOS=linux ; cd ./cmd/chromad && go build -o ../../chromad .)
|
||||
rice append -i ./cmd/chromad --exec=./chromad
|
||||
|
||||
upload: chromad
|
||||
scp chromad root@swapoff.org: && \
|
||||
ssh root@swapoff.org 'install -m755 ./chromad /srv/http/swapoff.org/bin && service chromad restart'
|
267
vendor/github.com/alecthomas/chroma/README.md
generated
vendored
267
vendor/github.com/alecthomas/chroma/README.md
generated
vendored
@ -1,267 +0,0 @@
|
||||
# Chroma — A general purpose syntax highlighter in pure Go [![Golang Documentation](https://godoc.org/github.com/alecthomas/chroma?status.svg)](https://godoc.org/github.com/alecthomas/chroma) [![Build Status](https://travis-ci.org/alecthomas/chroma.svg)](https://travis-ci.org/alecthomas/chroma) [![Gitter chat](https://badges.gitter.im/alecthomas.svg)](https://gitter.im/alecthomas/Lobby)
|
||||
|
||||
> **NOTE:** As Chroma has just been released, its API is still in flux. That said, the high-level interface should not change significantly.
|
||||
|
||||
Chroma takes source code and other structured text and converts it into syntax
|
||||
highlighted HTML, ANSI-coloured text, etc.
|
||||
|
||||
Chroma is based heavily on [Pygments](http://pygments.org/), and includes
|
||||
translators for Pygments lexers and styles.
|
||||
|
||||
<a id="markdown-table-of-contents" name="table-of-contents"></a>
|
||||
## Table of Contents
|
||||
|
||||
<!-- TOC -->
|
||||
|
||||
1. [Table of Contents](#table-of-contents)
|
||||
2. [Supported languages](#supported-languages)
|
||||
3. [Try it](#try-it)
|
||||
4. [Using the library](#using-the-library)
|
||||
1. [Quick start](#quick-start)
|
||||
2. [Identifying the language](#identifying-the-language)
|
||||
3. [Formatting the output](#formatting-the-output)
|
||||
4. [The HTML formatter](#the-html-formatter)
|
||||
5. [More detail](#more-detail)
|
||||
1. [Lexers](#lexers)
|
||||
2. [Formatters](#formatters)
|
||||
3. [Styles](#styles)
|
||||
6. [Command-line interface](#command-line-interface)
|
||||
7. [What's missing compared to Pygments?](#whats-missing-compared-to-pygments)
|
||||
|
||||
<!-- /TOC -->
|
||||
|
||||
<a id="markdown-supported-languages" name="supported-languages"></a>
|
||||
## Supported languages
|
||||
|
||||
Prefix | Language
|
||||
:----: | --------
|
||||
A | ABAP, ABNF, ActionScript, ActionScript 3, Ada, Angular2, ANTLR, ApacheConf, APL, AppleScript, Arduino, Awk
|
||||
B | Ballerina, Base Makefile, Bash, Batchfile, BlitzBasic, BNF, Brainfuck
|
||||
C | C, C#, C++, Cap'n Proto, Cassandra CQL, Ceylon, CFEngine3, cfstatement, ChaiScript, Cheetah, Clojure, CMake, COBOL, CoffeeScript, Common Lisp, Coq, Crystal, CSS, Cython
|
||||
D | D, Dart, Diff, Django/Jinja, Docker, DTD
|
||||
E | EBNF, Elixir, Elm, EmacsLisp, Erlang
|
||||
F | Factor, Fish, Forth, Fortran, FSharp
|
||||
G | GAS, GDScript, Genshi, Genshi HTML, Genshi Text, GLSL, Gnuplot, Go, Go HTML Template, Go Text Template, GraphQL, Groovy
|
||||
H | Handlebars, Haskell, Haxe, HCL, Hexdump, HTML, HTTP, Hy
|
||||
I | Idris, INI, Io
|
||||
J | J, Java, JavaScript, JSON, Julia, Jungle
|
||||
K | Kotlin
|
||||
L | Lighttpd configuration file, LLVM, Lua
|
||||
M | Mako, markdown, Mason, Mathematica, Matlab, MiniZinc, MLIR, Modula-2, MonkeyC, MorrowindScript, Myghty, MySQL
|
||||
N | NASM, Newspeak, Nginx configuration file, Nim, Nix
|
||||
O | Objective-C, OCaml, Octave, OpenSCAD, Org Mode
|
||||
P | PacmanConf, Perl, PHP, Pig, PkgConfig, PL/pgSQL, plaintext, PostgreSQL SQL dialect, PostScript, POVRay, PowerShell, Prolog, Protocol Buffer, Puppet, Python, Python 3
|
||||
Q | QBasic
|
||||
R | R, Racket, Ragel, react, reg, reStructuredText, Rexx, Ruby, Rust
|
||||
S | Sass, Scala, Scheme, Scilab, SCSS, Smalltalk, Smarty, SML, Snobol, Solidity, SPARQL, SQL, SquidConf, Swift, SYSTEMD, systemverilog
|
||||
T | TableGen, TASM, Tcl, Tcsh, Termcap, Terminfo, Terraform, TeX, Thrift, TOML, TradingView, Transact-SQL, Turing, Turtle, Twig, TypeScript, TypoScript, TypoScriptCssData, TypoScriptHtmlData
|
||||
V | VB.net, verilog, VHDL, VimL, vue
|
||||
W | WDTE
|
||||
X | XML, Xorg
|
||||
Y | YAML
|
||||
|
||||
|
||||
_I will attempt to keep this section up to date, but an authoritative list can be
|
||||
displayed with `chroma --list`._
|
||||
|
||||
<a id="markdown-try-it" name="try-it"></a>
|
||||
## Try it
|
||||
|
||||
Try out various languages and styles on the [Chroma Playground](https://swapoff.org/chroma/playground/).
|
||||
|
||||
<a id="markdown-using-the-library" name="using-the-library"></a>
|
||||
## Using the library
|
||||
|
||||
Chroma, like Pygments, has the concepts of
|
||||
[lexers](https://github.com/alecthomas/chroma/tree/master/lexers),
|
||||
[formatters](https://github.com/alecthomas/chroma/tree/master/formatters) and
|
||||
[styles](https://github.com/alecthomas/chroma/tree/master/styles).
|
||||
|
||||
Lexers convert source text into a stream of tokens, styles specify how token
|
||||
types are mapped to colours, and formatters convert tokens and styles into
|
||||
formatted output.
|
||||
|
||||
A package exists for each of these, containing a global `Registry` variable
|
||||
with all of the registered implementations. There are also helper functions
|
||||
for using the registry in each package, such as looking up lexers by name or
|
||||
matching filenames, etc.
|
||||
|
||||
In all cases, if a lexer, formatter or style can not be determined, `nil` will
|
||||
be returned. In this situation you may want to default to the `Fallback`
|
||||
value in each respective package, which provides sane defaults.
|
||||
|
||||
<a id="markdown-quick-start" name="quick-start"></a>
|
||||
### Quick start
|
||||
|
||||
A convenience function exists that can be used to simply format some source
|
||||
text, without any effort:
|
||||
|
||||
```go
|
||||
err := quick.Highlight(os.Stdout, someSourceCode, "go", "html", "monokai")
|
||||
```
|
||||
|
||||
<a id="markdown-identifying-the-language" name="identifying-the-language"></a>
|
||||
### Identifying the language
|
||||
|
||||
To highlight code, you'll first have to identify what language the code is
|
||||
written in. There are three primary ways to do that:
|
||||
|
||||
1. Detect the language from its filename.
|
||||
|
||||
```go
|
||||
lexer := lexers.Match("foo.go")
|
||||
```
|
||||
|
||||
3. Explicitly specify the language by its Chroma syntax ID (a full list is available from `lexers.Names()`).
|
||||
|
||||
```go
|
||||
lexer := lexers.Get("go")
|
||||
```
|
||||
|
||||
3. Detect the language from its content.
|
||||
|
||||
```go
|
||||
lexer := lexers.Analyse("package main\n\nfunc main()\n{\n}\n")
|
||||
```
|
||||
|
||||
In all cases, `nil` will be returned if the language can not be identified.
|
||||
|
||||
```go
|
||||
if lexer == nil {
|
||||
lexer = lexers.Fallback
|
||||
}
|
||||
```
|
||||
|
||||
At this point, it should be noted that some lexers can be extremely chatty. To
|
||||
mitigate this, you can use the coalescing lexer to coalesce runs of identical
|
||||
token types into a single token:
|
||||
|
||||
```go
|
||||
lexer = chroma.Coalesce(lexer)
|
||||
```
|
||||
|
||||
<a id="markdown-formatting-the-output" name="formatting-the-output"></a>
|
||||
### Formatting the output
|
||||
|
||||
Once a language is identified you will need to pick a formatter and a style (theme).
|
||||
|
||||
```go
|
||||
style := styles.Get("swapoff")
|
||||
if style == nil {
|
||||
style = styles.Fallback
|
||||
}
|
||||
formatter := formatters.Get("html")
|
||||
if formatter == nil {
|
||||
formatter = formatters.Fallback
|
||||
}
|
||||
```
|
||||
|
||||
Then obtain an iterator over the tokens:
|
||||
|
||||
```go
|
||||
contents, err := ioutil.ReadAll(r)
|
||||
iterator, err := lexer.Tokenise(nil, string(contents))
|
||||
```
|
||||
|
||||
And finally, format the tokens from the iterator:
|
||||
|
||||
```go
|
||||
err := formatter.Format(w, style, iterator)
|
||||
```
|
||||
|
||||
<a id="markdown-the-html-formatter" name="the-html-formatter"></a>
|
||||
### The HTML formatter
|
||||
|
||||
By default the `html` registered formatter generates standalone HTML with
|
||||
embedded CSS. More flexibility is available through the `formatters/html` package.
|
||||
|
||||
Firstly, the output generated by the formatter can be customised with the
|
||||
following constructor options:
|
||||
|
||||
- `Standalone()` - generate standalone HTML with embedded CSS.
|
||||
- `WithClasses()` - use classes rather than inlined style attributes.
|
||||
- `ClassPrefix(prefix)` - prefix each generated CSS class.
|
||||
- `TabWidth(width)` - Set the rendered tab width, in characters.
|
||||
- `WithLineNumbers()` - Render line numbers (style with `LineNumbers`).
|
||||
- `LinkableLineNumbers()` - Make the line numbers linkable.
|
||||
- `HighlightLines(ranges)` - Highlight lines in these ranges (style with `LineHighlight`).
|
||||
- `LineNumbersInTable()` - Use a table for formatting line numbers and code, rather than spans.
|
||||
|
||||
If `WithClasses()` is used, the corresponding CSS can be obtained from the formatter with:
|
||||
|
||||
```go
|
||||
formatter := html.New(html.WithClasses())
|
||||
err := formatter.WriteCSS(w, style)
|
||||
```
|
||||
|
||||
<a id="markdown-more-detail" name="more-detail"></a>
|
||||
## More detail
|
||||
|
||||
<a id="markdown-lexers" name="lexers"></a>
|
||||
### Lexers
|
||||
|
||||
See the [Pygments documentation](http://pygments.org/docs/lexerdevelopment/)
|
||||
for details on implementing lexers. Most concepts apply directly to Chroma,
|
||||
but see existing lexer implementations for real examples.
|
||||
|
||||
In many cases lexers can be automatically converted directly from Pygments by
|
||||
using the included Python 3 script `pygments2chroma.py`. I use something like
|
||||
the following:
|
||||
|
||||
```sh
|
||||
python3 ~/Projects/chroma/_tools/pygments2chroma.py \
|
||||
pygments.lexers.jvm.KotlinLexer \
|
||||
> ~/Projects/chroma/lexers/kotlin.go \
|
||||
&& gofmt -s -w ~/Projects/chroma/lexers/*.go
|
||||
```
|
||||
|
||||
See notes in [pygments-lexers.go](https://github.com/alecthomas/chroma/blob/master/pygments-lexers.txt)
|
||||
for a list of lexers, and notes on some of the issues importing them.
|
||||
|
||||
<a id="markdown-formatters" name="formatters"></a>
|
||||
### Formatters
|
||||
|
||||
Chroma supports HTML output, as well as terminal output in 8 colour, 256 colour, and true-colour.
|
||||
|
||||
A `noop` formatter is included that outputs the token text only, and a `tokens`
|
||||
formatter outputs raw tokens. The latter is useful for debugging lexers.
|
||||
|
||||
<a id="markdown-styles" name="styles"></a>
|
||||
### Styles
|
||||
|
||||
Chroma styles use the [same syntax](http://pygments.org/docs/styles/) as Pygments.
|
||||
|
||||
All Pygments styles have been converted to Chroma using the `_tools/style.py` script.
|
||||
|
||||
When you work with one of [Chroma's styles](https://github.com/alecthomas/chroma/tree/master/styles), know that the `chroma.Background` token type provides the default style for tokens. It does so by defining a foreground color and background color.
|
||||
|
||||
For example, this gives each token name not defined in the style a default color of `#f8f8f8` and uses `#000000` for the highlighted code block's background:
|
||||
|
||||
~~~go
|
||||
chroma.Background: "#f8f8f2 bg:#000000",
|
||||
~~~
|
||||
|
||||
Also, token types in a style file are hierarchical. For instance, when `CommentSpecial` is not defined, Chroma uses the token style from `Comment`. So when several comment tokens use the same color, you'll only need to define `Comment` and override the one that has a different color.
|
||||
|
||||
For a quick overview of the available styles and how they look, check out the [Chroma Style Gallery](https://xyproto.github.io/splash/docs/).
|
||||
|
||||
<a id="markdown-command-line-interface" name="command-line-interface"></a>
|
||||
## Command-line interface
|
||||
|
||||
A command-line interface to Chroma is included. It can be installed with:
|
||||
|
||||
```sh
|
||||
go get -u github.com/alecthomas/chroma/cmd/chroma
|
||||
```
|
||||
|
||||
<a id="markdown-whats-missing-compared-to-pygments" name="whats-missing-compared-to-pygments"></a>
|
||||
## What's missing compared to Pygments?
|
||||
|
||||
- Quite a few lexers, for various reasons (pull-requests welcome):
|
||||
- Pygments lexers for complex languages often include custom code to
|
||||
handle certain aspects, such as Perl6's ability to nest code inside
|
||||
regular expressions. These require time and effort to convert.
|
||||
- I mostly only converted languages I had heard of, to reduce the porting cost.
|
||||
- Some more esoteric features of Pygments are omitted for simplicity.
|
||||
- Though the Chroma API supports content detection, very few languages support them.
|
||||
I have plans to implement a statistical analyser at some point, but not enough time.
|
35
vendor/github.com/alecthomas/chroma/coalesce.go
generated
vendored
35
vendor/github.com/alecthomas/chroma/coalesce.go
generated
vendored
@ -1,35 +0,0 @@
|
||||
package chroma
|
||||
|
||||
// Coalesce is a Lexer interceptor that collapses runs of common types into a single token.
|
||||
func Coalesce(lexer Lexer) Lexer { return &coalescer{lexer} }
|
||||
|
||||
type coalescer struct{ Lexer }
|
||||
|
||||
func (d *coalescer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) {
|
||||
var prev Token
|
||||
it, err := d.Lexer.Tokenise(options, text)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return func() Token {
|
||||
for token := it(); token != (EOF); token = it() {
|
||||
if len(token.Value) == 0 {
|
||||
continue
|
||||
}
|
||||
if prev == EOF {
|
||||
prev = token
|
||||
} else {
|
||||
if prev.Type == token.Type && len(prev.Value) < 8192 {
|
||||
prev.Value += token.Value
|
||||
} else {
|
||||
out := prev
|
||||
prev = token
|
||||
return out
|
||||
}
|
||||
}
|
||||
}
|
||||
out := prev
|
||||
prev = EOF
|
||||
return out
|
||||
}, nil
|
||||
}
|
164
vendor/github.com/alecthomas/chroma/colour.go
generated
vendored
164
vendor/github.com/alecthomas/chroma/colour.go
generated
vendored
@ -1,164 +0,0 @@
|
||||
package chroma
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ANSI2RGB maps ANSI colour names, as supported by Chroma, to hex RGB values.
|
||||
var ANSI2RGB = map[string]string{
|
||||
"#ansiblack": "000000",
|
||||
"#ansidarkred": "7f0000",
|
||||
"#ansidarkgreen": "007f00",
|
||||
"#ansibrown": "7f7fe0",
|
||||
"#ansidarkblue": "00007f",
|
||||
"#ansipurple": "7f007f",
|
||||
"#ansiteal": "007f7f",
|
||||
"#ansilightgray": "e5e5e5",
|
||||
// Normal
|
||||
"#ansidarkgray": "555555",
|
||||
"#ansired": "ff0000",
|
||||
"#ansigreen": "00ff00",
|
||||
"#ansiyellow": "ffff00",
|
||||
"#ansiblue": "0000ff",
|
||||
"#ansifuchsia": "ff00ff",
|
||||
"#ansiturquoise": "00ffff",
|
||||
"#ansiwhite": "ffffff",
|
||||
|
||||
// Aliases without the "ansi" prefix, because...why?
|
||||
"#black": "000000",
|
||||
"#darkred": "7f0000",
|
||||
"#darkgreen": "007f00",
|
||||
"#brown": "7f7fe0",
|
||||
"#darkblue": "00007f",
|
||||
"#purple": "7f007f",
|
||||
"#teal": "007f7f",
|
||||
"#lightgray": "e5e5e5",
|
||||
// Normal
|
||||
"#darkgray": "555555",
|
||||
"#red": "ff0000",
|
||||
"#green": "00ff00",
|
||||
"#yellow": "ffff00",
|
||||
"#blue": "0000ff",
|
||||
"#fuchsia": "ff00ff",
|
||||
"#turquoise": "00ffff",
|
||||
"#white": "ffffff",
|
||||
}
|
||||
|
||||
// Colour represents an RGB colour.
|
||||
type Colour int32
|
||||
|
||||
// NewColour creates a Colour directly from RGB values.
|
||||
func NewColour(r, g, b uint8) Colour {
|
||||
return ParseColour(fmt.Sprintf("%02x%02x%02x", r, g, b))
|
||||
}
|
||||
|
||||
// Distance between this colour and another.
|
||||
//
|
||||
// This uses the approach described here (https://www.compuphase.com/cmetric.htm).
|
||||
// This is not as accurate as LAB, et. al. but is *vastly* simpler and sufficient for our needs.
|
||||
func (c Colour) Distance(e2 Colour) float64 {
|
||||
ar, ag, ab := int64(c.Red()), int64(c.Green()), int64(c.Blue())
|
||||
br, bg, bb := int64(e2.Red()), int64(e2.Green()), int64(e2.Blue())
|
||||
rmean := (ar + br) / 2
|
||||
r := ar - br
|
||||
g := ag - bg
|
||||
b := ab - bb
|
||||
return math.Sqrt(float64((((512 + rmean) * r * r) >> 8) + 4*g*g + (((767 - rmean) * b * b) >> 8)))
|
||||
}
|
||||
|
||||
// Brighten returns a copy of this colour with its brightness adjusted.
|
||||
//
|
||||
// If factor is negative, the colour is darkened.
|
||||
//
|
||||
// Uses approach described here (http://www.pvladov.com/2012/09/make-color-lighter-or-darker.html).
|
||||
func (c Colour) Brighten(factor float64) Colour {
|
||||
r := float64(c.Red())
|
||||
g := float64(c.Green())
|
||||
b := float64(c.Blue())
|
||||
|
||||
if factor < 0 {
|
||||
factor++
|
||||
r *= factor
|
||||
g *= factor
|
||||
b *= factor
|
||||
} else {
|
||||
r = (255-r)*factor + r
|
||||
g = (255-g)*factor + g
|
||||
b = (255-b)*factor + b
|
||||
}
|
||||
return NewColour(uint8(r), uint8(g), uint8(b))
|
||||
}
|
||||
|
||||
// BrightenOrDarken brightens a colour if it is < 0.5 brighteness or darkens if > 0.5 brightness.
|
||||
func (c Colour) BrightenOrDarken(factor float64) Colour {
|
||||
if c.Brightness() < 0.5 {
|
||||
return c.Brighten(factor)
|
||||
}
|
||||
return c.Brighten(-factor)
|
||||
}
|
||||
|
||||
// Brightness of the colour (roughly) in the range 0.0 to 1.0
|
||||
func (c Colour) Brightness() float64 {
|
||||
return (float64(c.Red()) + float64(c.Green()) + float64(c.Blue())) / 255.0 / 3.0
|
||||
}
|
||||
|
||||
// ParseColour in the forms #rgb, #rrggbb, #ansi<colour>, or #<colour>.
|
||||
// Will return an "unset" colour if invalid.
|
||||
func ParseColour(colour string) Colour {
|
||||
colour = normaliseColour(colour)
|
||||
n, err := strconv.ParseUint(colour, 16, 32)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return Colour(n + 1)
|
||||
}
|
||||
|
||||
// MustParseColour is like ParseColour except it panics if the colour is invalid.
|
||||
//
|
||||
// Will panic if colour is in an invalid format.
|
||||
func MustParseColour(colour string) Colour {
|
||||
parsed := ParseColour(colour)
|
||||
if !parsed.IsSet() {
|
||||
panic(fmt.Errorf("invalid colour %q", colour))
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
|
||||
// IsSet returns true if the colour is set.
|
||||
func (c Colour) IsSet() bool { return c != 0 }
|
||||
|
||||
func (c Colour) String() string { return fmt.Sprintf("#%06x", int(c-1)) }
|
||||
func (c Colour) GoString() string { return fmt.Sprintf("Colour(0x%06x)", int(c-1)) }
|
||||
|
||||
// Red component of colour.
|
||||
func (c Colour) Red() uint8 { return uint8(((c - 1) >> 16) & 0xff) }
|
||||
|
||||
// Green component of colour.
|
||||
func (c Colour) Green() uint8 { return uint8(((c - 1) >> 8) & 0xff) }
|
||||
|
||||
// Blue component of colour.
|
||||
func (c Colour) Blue() uint8 { return uint8((c - 1) & 0xff) }
|
||||
|
||||
// Colours is an orderable set of colours.
|
||||
type Colours []Colour
|
||||
|
||||
func (c Colours) Len() int { return len(c) }
|
||||
func (c Colours) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
|
||||
func (c Colours) Less(i, j int) bool { return c[i] < c[j] }
|
||||
|
||||
// Convert colours to #rrggbb.
|
||||
func normaliseColour(colour string) string {
|
||||
if ansi, ok := ANSI2RGB[colour]; ok {
|
||||
return ansi
|
||||
}
|
||||
if strings.HasPrefix(colour, "#") {
|
||||
colour = colour[1:]
|
||||
if len(colour) == 3 {
|
||||
return colour[0:1] + colour[0:1] + colour[1:2] + colour[1:2] + colour[2:3] + colour[2:3]
|
||||
}
|
||||
}
|
||||
return colour
|
||||
}
|
137
vendor/github.com/alecthomas/chroma/delegate.go
generated
vendored
137
vendor/github.com/alecthomas/chroma/delegate.go
generated
vendored
@ -1,137 +0,0 @@
|
||||
package chroma
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
type delegatingLexer struct {
|
||||
root Lexer
|
||||
language Lexer
|
||||
}
|
||||
|
||||
// DelegatingLexer combines two lexers to handle the common case of a language embedded inside another, such as PHP
|
||||
// inside HTML or PHP inside plain text.
|
||||
//
|
||||
// It takes two lexer as arguments: a root lexer and a language lexer. First everything is scanned using the language
|
||||
// lexer, which must return "Other" for unrecognised tokens. Then all "Other" tokens are lexed using the root lexer.
|
||||
// Finally, these two sets of tokens are merged.
|
||||
//
|
||||
// The lexers from the template lexer package use this base lexer.
|
||||
func DelegatingLexer(root Lexer, language Lexer) Lexer {
|
||||
return &delegatingLexer{
|
||||
root: root,
|
||||
language: language,
|
||||
}
|
||||
}
|
||||
|
||||
func (d *delegatingLexer) Config() *Config {
|
||||
return d.language.Config()
|
||||
}
|
||||
|
||||
// An insertion is the character range where language tokens should be inserted.
|
||||
type insertion struct {
|
||||
start, end int
|
||||
tokens []Token
|
||||
}
|
||||
|
||||
func (d *delegatingLexer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) { // nolint: gocognit
|
||||
tokens, err := Tokenise(Coalesce(d.language), options, text)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Compute insertions and gather "Other" tokens.
|
||||
others := &bytes.Buffer{}
|
||||
insertions := []*insertion{}
|
||||
var insert *insertion
|
||||
offset := 0
|
||||
var last Token
|
||||
for _, t := range tokens {
|
||||
if t.Type == Other {
|
||||
if last != EOF && insert != nil && last.Type != Other {
|
||||
insert.end = offset
|
||||
}
|
||||
others.WriteString(t.Value)
|
||||
} else {
|
||||
if last == EOF || last.Type == Other {
|
||||
insert = &insertion{start: offset}
|
||||
insertions = append(insertions, insert)
|
||||
}
|
||||
insert.tokens = append(insert.tokens, t)
|
||||
}
|
||||
last = t
|
||||
offset += len(t.Value)
|
||||
}
|
||||
|
||||
if len(insertions) == 0 {
|
||||
return d.root.Tokenise(options, text)
|
||||
}
|
||||
|
||||
// Lex the other tokens.
|
||||
rootTokens, err := Tokenise(Coalesce(d.root), options, others.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Interleave the two sets of tokens.
|
||||
var out []Token
|
||||
offset = 0 // Offset into text.
|
||||
tokenIndex := 0
|
||||
nextToken := func() Token {
|
||||
if tokenIndex >= len(rootTokens) {
|
||||
return EOF
|
||||
}
|
||||
t := rootTokens[tokenIndex]
|
||||
tokenIndex++
|
||||
return t
|
||||
}
|
||||
insertionIndex := 0
|
||||
nextInsertion := func() *insertion {
|
||||
if insertionIndex >= len(insertions) {
|
||||
return nil
|
||||
}
|
||||
i := insertions[insertionIndex]
|
||||
insertionIndex++
|
||||
return i
|
||||
}
|
||||
t := nextToken()
|
||||
i := nextInsertion()
|
||||
for t != EOF || i != nil {
|
||||
// fmt.Printf("%d->%d:%q %d->%d:%q\n", offset, offset+len(t.Value), t.Value, i.start, i.end, Stringify(i.tokens...))
|
||||
if t == EOF || (i != nil && i.start < offset+len(t.Value)) {
|
||||
var l Token
|
||||
l, t = splitToken(t, i.start-offset)
|
||||
if l != EOF {
|
||||
out = append(out, l)
|
||||
offset += len(l.Value)
|
||||
}
|
||||
out = append(out, i.tokens...)
|
||||
offset += i.end - i.start
|
||||
if t == EOF {
|
||||
t = nextToken()
|
||||
}
|
||||
i = nextInsertion()
|
||||
} else {
|
||||
out = append(out, t)
|
||||
offset += len(t.Value)
|
||||
t = nextToken()
|
||||
}
|
||||
}
|
||||
return Literator(out...), nil
|
||||
}
|
||||
|
||||
func splitToken(t Token, offset int) (l Token, r Token) {
|
||||
if t == EOF {
|
||||
return EOF, EOF
|
||||
}
|
||||
if offset == 0 {
|
||||
return EOF, t
|
||||
}
|
||||
if offset == len(t.Value) {
|
||||
return t, EOF
|
||||
}
|
||||
l = t.Clone()
|
||||
r = t.Clone()
|
||||
l.Value = l.Value[:offset]
|
||||
r.Value = r.Value[offset:]
|
||||
return
|
||||
}
|
7
vendor/github.com/alecthomas/chroma/doc.go
generated
vendored
7
vendor/github.com/alecthomas/chroma/doc.go
generated
vendored
@ -1,7 +0,0 @@
|
||||
// Package chroma takes source code and other structured text and converts it into syntax highlighted HTML, ANSI-
|
||||
// coloured text, etc.
|
||||
//
|
||||
// Chroma is based heavily on Pygments, and includes translators for Pygments lexers and styles.
|
||||
//
|
||||
// For more information, go here: https://github.com/alecthomas/chroma
|
||||
package chroma
|
43
vendor/github.com/alecthomas/chroma/formatter.go
generated
vendored
43
vendor/github.com/alecthomas/chroma/formatter.go
generated
vendored
@ -1,43 +0,0 @@
|
||||
package chroma
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
// A Formatter for Chroma lexers.
|
||||
type Formatter interface {
|
||||
// Format returns a formatting function for tokens.
|
||||
//
|
||||
// If the iterator panics, the Formatter should recover.
|
||||
Format(w io.Writer, style *Style, iterator Iterator) error
|
||||
}
|
||||
|
||||
// A FormatterFunc is a Formatter implemented as a function.
|
||||
//
|
||||
// Guards against iterator panics.
|
||||
type FormatterFunc func(w io.Writer, style *Style, iterator Iterator) error
|
||||
|
||||
func (f FormatterFunc) Format(w io.Writer, s *Style, it Iterator) (err error) { // nolint
|
||||
defer func() {
|
||||
if perr := recover(); perr != nil {
|
||||
err = perr.(error)
|
||||
}
|
||||
}()
|
||||
return f(w, s, it)
|
||||
}
|
||||
|
||||
type recoveringFormatter struct {
|
||||
Formatter
|
||||
}
|
||||
|
||||
func (r recoveringFormatter) Format(w io.Writer, s *Style, it Iterator) (err error) {
|
||||
defer func() {
|
||||
if perr := recover(); perr != nil {
|
||||
err = perr.(error)
|
||||
}
|
||||
}()
|
||||
return r.Formatter.Format(w, s, it)
|
||||
}
|
||||
|
||||
// RecoveringFormatter wraps a formatter with panic recovery.
|
||||
func RecoveringFormatter(formatter Formatter) Formatter { return recoveringFormatter{formatter} }
|
57
vendor/github.com/alecthomas/chroma/formatters/api.go
generated
vendored
57
vendor/github.com/alecthomas/chroma/formatters/api.go
generated
vendored
@ -1,57 +0,0 @@
|
||||
package formatters
|
||||
|
||||
import (
|
||||
"io"
|
||||
"sort"
|
||||
|
||||
"github.com/alecthomas/chroma"
|
||||
"github.com/alecthomas/chroma/formatters/html"
|
||||
"github.com/alecthomas/chroma/formatters/svg"
|
||||
)
|
||||
|
||||
var (
|
||||
// NoOp formatter.
|
||||
NoOp = Register("noop", chroma.FormatterFunc(func(w io.Writer, s *chroma.Style, iterator chroma.Iterator) error {
|
||||
for t := iterator(); t != chroma.EOF; t = iterator() {
|
||||
if _, err := io.WriteString(w, t.Value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}))
|
||||
// Default HTML formatter outputs self-contained HTML.
|
||||
htmlFull = Register("html", html.New(html.Standalone(true), html.WithClasses(true))) // nolint
|
||||
SVG = Register("svg", svg.New(svg.EmbedFont("Liberation Mono", svg.FontLiberationMono, svg.WOFF)))
|
||||
)
|
||||
|
||||
// Fallback formatter.
|
||||
var Fallback = NoOp
|
||||
|
||||
// Registry of Formatters.
|
||||
var Registry = map[string]chroma.Formatter{}
|
||||
|
||||
// Names of registered formatters.
|
||||
func Names() []string {
|
||||
out := []string{}
|
||||
for name := range Registry {
|
||||
out = append(out, name)
|
||||
}
|
||||
sort.Strings(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// Get formatter by name.
|
||||
//
|
||||
// If the given formatter is not found, the Fallback formatter will be returned.
|
||||
func Get(name string) chroma.Formatter {
|
||||
if f, ok := Registry[name]; ok {
|
||||
return f
|
||||
}
|
||||
return Fallback
|
||||
}
|
||||
|
||||
// Register a named formatter.
|
||||
func Register(name string, formatter chroma.Formatter) chroma.Formatter {
|
||||
Registry[name] = formatter
|
||||
return formatter
|
||||
}
|
435
vendor/github.com/alecthomas/chroma/formatters/html/html.go
generated
vendored
435
vendor/github.com/alecthomas/chroma/formatters/html/html.go
generated
vendored
@ -1,435 +0,0 @@
|
||||
package html
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html"
|
||||
"io"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/chroma"
|
||||
)
|
||||
|
||||
// Option sets an option of the HTML formatter.
|
||||
type Option func(f *Formatter)
|
||||
|
||||
// Standalone configures the HTML formatter for generating a standalone HTML document.
|
||||
func Standalone(b bool) Option { return func(f *Formatter) { f.standalone = b } }
|
||||
|
||||
// ClassPrefix sets the CSS class prefix.
|
||||
func ClassPrefix(prefix string) Option { return func(f *Formatter) { f.prefix = prefix } }
|
||||
|
||||
// WithClasses emits HTML using CSS classes, rather than inline styles.
|
||||
func WithClasses(b bool) Option { return func(f *Formatter) { f.Classes = b } }
|
||||
|
||||
// TabWidth sets the number of characters for a tab. Defaults to 8.
|
||||
func TabWidth(width int) Option { return func(f *Formatter) { f.tabWidth = width } }
|
||||
|
||||
// PreventSurroundingPre prevents the surrounding pre tags around the generated code.
|
||||
func PreventSurroundingPre(b bool) Option {
|
||||
return func(f *Formatter) {
|
||||
if b {
|
||||
f.preWrapper = nopPreWrapper
|
||||
} else {
|
||||
f.preWrapper = defaultPreWrapper
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithPreWrapper allows control of the surrounding pre tags.
|
||||
func WithPreWrapper(wrapper PreWrapper) Option {
|
||||
return func(f *Formatter) {
|
||||
f.preWrapper = wrapper
|
||||
}
|
||||
}
|
||||
|
||||
// WithLineNumbers formats output with line numbers.
|
||||
func WithLineNumbers(b bool) Option {
|
||||
return func(f *Formatter) {
|
||||
f.lineNumbers = b
|
||||
}
|
||||
}
|
||||
|
||||
// LineNumbersInTable will, when combined with WithLineNumbers, separate the line numbers
|
||||
// and code in table td's, which make them copy-and-paste friendly.
|
||||
func LineNumbersInTable(b bool) Option {
|
||||
return func(f *Formatter) {
|
||||
f.lineNumbersInTable = b
|
||||
}
|
||||
}
|
||||
|
||||
// LinkableLineNumbers decorates the line numbers HTML elements with an "id"
|
||||
// attribute so they can be linked.
|
||||
func LinkableLineNumbers(b bool, prefix string) Option {
|
||||
return func(f *Formatter) {
|
||||
f.linkableLineNumbers = b
|
||||
f.lineNumbersIDPrefix = prefix
|
||||
}
|
||||
}
|
||||
|
||||
// HighlightLines higlights the given line ranges with the Highlight style.
|
||||
//
|
||||
// A range is the beginning and ending of a range as 1-based line numbers, inclusive.
|
||||
func HighlightLines(ranges [][2]int) Option {
|
||||
return func(f *Formatter) {
|
||||
f.highlightRanges = ranges
|
||||
sort.Sort(f.highlightRanges)
|
||||
}
|
||||
}
|
||||
|
||||
// BaseLineNumber sets the initial number to start line numbering at. Defaults to 1.
|
||||
func BaseLineNumber(n int) Option {
|
||||
return func(f *Formatter) {
|
||||
f.baseLineNumber = n
|
||||
}
|
||||
}
|
||||
|
||||
// New HTML formatter.
|
||||
func New(options ...Option) *Formatter {
|
||||
f := &Formatter{
|
||||
baseLineNumber: 1,
|
||||
preWrapper: defaultPreWrapper,
|
||||
}
|
||||
for _, option := range options {
|
||||
option(f)
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
// PreWrapper defines the operations supported in WithPreWrapper.
|
||||
type PreWrapper interface {
|
||||
// Start is called to write a start <pre> element.
|
||||
// The code flag tells whether this block surrounds
|
||||
// highlighted code. This will be false when surrounding
|
||||
// line numbers.
|
||||
Start(code bool, styleAttr string) string
|
||||
|
||||
// End is called to write the end </pre> element.
|
||||
End(code bool) string
|
||||
}
|
||||
|
||||
type preWrapper struct {
|
||||
start func(code bool, styleAttr string) string
|
||||
end func(code bool) string
|
||||
}
|
||||
|
||||
func (p preWrapper) Start(code bool, styleAttr string) string {
|
||||
return p.start(code, styleAttr)
|
||||
}
|
||||
|
||||
func (p preWrapper) End(code bool) string {
|
||||
return p.end(code)
|
||||
}
|
||||
|
||||
var (
|
||||
nopPreWrapper = preWrapper{
|
||||
start: func(code bool, styleAttr string) string { return "" },
|
||||
end: func(code bool) string { return "" },
|
||||
}
|
||||
defaultPreWrapper = preWrapper{
|
||||
start: func(code bool, styleAttr string) string {
|
||||
return fmt.Sprintf("<pre%s>", styleAttr)
|
||||
},
|
||||
end: func(code bool) string {
|
||||
return "</pre>"
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// Formatter that generates HTML.
|
||||
type Formatter struct {
|
||||
standalone bool
|
||||
prefix string
|
||||
Classes bool // Exported field to detect when classes are being used
|
||||
preWrapper PreWrapper
|
||||
tabWidth int
|
||||
lineNumbers bool
|
||||
lineNumbersInTable bool
|
||||
linkableLineNumbers bool
|
||||
lineNumbersIDPrefix string
|
||||
highlightRanges highlightRanges
|
||||
baseLineNumber int
|
||||
}
|
||||
|
||||
type highlightRanges [][2]int
|
||||
|
||||
func (h highlightRanges) Len() int { return len(h) }
|
||||
func (h highlightRanges) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
|
||||
func (h highlightRanges) Less(i, j int) bool { return h[i][0] < h[j][0] }
|
||||
|
||||
func (f *Formatter) Format(w io.Writer, style *chroma.Style, iterator chroma.Iterator) (err error) {
|
||||
return f.writeHTML(w, style, iterator.Tokens())
|
||||
}
|
||||
|
||||
// We deliberately don't use html/template here because it is two orders of magnitude slower (benchmarked).
|
||||
//
|
||||
// OTOH we need to be super careful about correct escaping...
|
||||
func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.Token) (err error) { // nolint: gocyclo
|
||||
css := f.styleToCSS(style)
|
||||
if !f.Classes {
|
||||
for t, style := range css {
|
||||
css[t] = compressStyle(style)
|
||||
}
|
||||
}
|
||||
if f.standalone {
|
||||
fmt.Fprint(w, "<html>\n")
|
||||
if f.Classes {
|
||||
fmt.Fprint(w, "<style type=\"text/css\">\n")
|
||||
err = f.WriteCSS(w, style)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(w, "body { %s; }\n", css[chroma.Background])
|
||||
fmt.Fprint(w, "</style>")
|
||||
}
|
||||
fmt.Fprintf(w, "<body%s>\n", f.styleAttr(css, chroma.Background))
|
||||
}
|
||||
|
||||
wrapInTable := f.lineNumbers && f.lineNumbersInTable
|
||||
|
||||
lines := chroma.SplitTokensIntoLines(tokens)
|
||||
lineDigits := len(fmt.Sprintf("%d", f.baseLineNumber+len(lines)-1))
|
||||
highlightIndex := 0
|
||||
|
||||
if wrapInTable {
|
||||
// List line numbers in its own <td>
|
||||
fmt.Fprintf(w, "<div%s>\n", f.styleAttr(css, chroma.Background))
|
||||
fmt.Fprintf(w, "<table%s><tr>", f.styleAttr(css, chroma.LineTable))
|
||||
fmt.Fprintf(w, "<td%s>\n", f.styleAttr(css, chroma.LineTableTD))
|
||||
fmt.Fprintf(w, f.preWrapper.Start(false, f.styleAttr(css, chroma.Background)))
|
||||
for index := range lines {
|
||||
line := f.baseLineNumber + index
|
||||
highlight, next := f.shouldHighlight(highlightIndex, line)
|
||||
if next {
|
||||
highlightIndex++
|
||||
}
|
||||
if highlight {
|
||||
fmt.Fprintf(w, "<span%s>", f.styleAttr(css, chroma.LineHighlight))
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "<span%s%s>%*d\n</span>", f.styleAttr(css, chroma.LineNumbersTable), f.lineIDAttribute(line), lineDigits, line)
|
||||
|
||||
if highlight {
|
||||
fmt.Fprintf(w, "</span>")
|
||||
}
|
||||
}
|
||||
fmt.Fprint(w, f.preWrapper.End(false))
|
||||
fmt.Fprint(w, "</td>\n")
|
||||
fmt.Fprintf(w, "<td%s>\n", f.styleAttr(css, chroma.LineTableTD, "width:100%"))
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, f.preWrapper.Start(true, f.styleAttr(css, chroma.Background)))
|
||||
|
||||
highlightIndex = 0
|
||||
for index, tokens := range lines {
|
||||
// 1-based line number.
|
||||
line := f.baseLineNumber + index
|
||||
highlight, next := f.shouldHighlight(highlightIndex, line)
|
||||
if next {
|
||||
highlightIndex++
|
||||
}
|
||||
if highlight {
|
||||
fmt.Fprintf(w, "<span%s>", f.styleAttr(css, chroma.LineHighlight))
|
||||
}
|
||||
|
||||
if f.lineNumbers && !wrapInTable {
|
||||
fmt.Fprintf(w, "<span%s%s>%*d</span>", f.styleAttr(css, chroma.LineNumbers), f.lineIDAttribute(line), lineDigits, line)
|
||||
}
|
||||
|
||||
for _, token := range tokens {
|
||||
html := html.EscapeString(token.String())
|
||||
attr := f.styleAttr(css, token.Type)
|
||||
if attr != "" {
|
||||
html = fmt.Sprintf("<span%s>%s</span>", attr, html)
|
||||
}
|
||||
fmt.Fprint(w, html)
|
||||
}
|
||||
if highlight {
|
||||
fmt.Fprintf(w, "</span>")
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, f.preWrapper.End(true))
|
||||
|
||||
if wrapInTable {
|
||||
fmt.Fprint(w, "</td></tr></table>\n")
|
||||
fmt.Fprint(w, "</div>\n")
|
||||
}
|
||||
|
||||
if f.standalone {
|
||||
fmt.Fprint(w, "\n</body>\n")
|
||||
fmt.Fprint(w, "</html>\n")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Formatter) lineIDAttribute(line int) string {
|
||||
if !f.linkableLineNumbers {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf(" id=\"%s%d\"", f.lineNumbersIDPrefix, line)
|
||||
}
|
||||
|
||||
func (f *Formatter) shouldHighlight(highlightIndex, line int) (bool, bool) {
|
||||
next := false
|
||||
for highlightIndex < len(f.highlightRanges) && line > f.highlightRanges[highlightIndex][1] {
|
||||
highlightIndex++
|
||||
next = true
|
||||
}
|
||||
if highlightIndex < len(f.highlightRanges) {
|
||||
hrange := f.highlightRanges[highlightIndex]
|
||||
if line >= hrange[0] && line <= hrange[1] {
|
||||
return true, next
|
||||
}
|
||||
}
|
||||
return false, next
|
||||
}
|
||||
|
||||
func (f *Formatter) class(t chroma.TokenType) string {
|
||||
for t != 0 {
|
||||
if cls, ok := chroma.StandardTypes[t]; ok {
|
||||
if cls != "" {
|
||||
return f.prefix + cls
|
||||
}
|
||||
return ""
|
||||
}
|
||||
t = t.Parent()
|
||||
}
|
||||
if cls := chroma.StandardTypes[t]; cls != "" {
|
||||
return f.prefix + cls
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (f *Formatter) styleAttr(styles map[chroma.TokenType]string, tt chroma.TokenType, extraCSS ...string) string {
|
||||
if f.Classes {
|
||||
cls := f.class(tt)
|
||||
if cls == "" {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf(` class="%s"`, cls)
|
||||
}
|
||||
if _, ok := styles[tt]; !ok {
|
||||
tt = tt.SubCategory()
|
||||
if _, ok := styles[tt]; !ok {
|
||||
tt = tt.Category()
|
||||
if _, ok := styles[tt]; !ok {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
css := []string{styles[tt]}
|
||||
css = append(css, extraCSS...)
|
||||
return fmt.Sprintf(` style="%s"`, strings.Join(css, ";"))
|
||||
}
|
||||
|
||||
func (f *Formatter) tabWidthStyle() string {
|
||||
if f.tabWidth != 0 && f.tabWidth != 8 {
|
||||
return fmt.Sprintf("; -moz-tab-size: %[1]d; -o-tab-size: %[1]d; tab-size: %[1]d", f.tabWidth)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// WriteCSS writes CSS style definitions (without any surrounding HTML).
|
||||
func (f *Formatter) WriteCSS(w io.Writer, style *chroma.Style) error {
|
||||
css := f.styleToCSS(style)
|
||||
// Special-case background as it is mapped to the outer ".chroma" class.
|
||||
if _, err := fmt.Fprintf(w, "/* %s */ .%schroma { %s }\n", chroma.Background, f.prefix, css[chroma.Background]); err != nil {
|
||||
return err
|
||||
}
|
||||
// Special-case code column of table to expand width.
|
||||
if f.lineNumbers && f.lineNumbersInTable {
|
||||
if _, err := fmt.Fprintf(w, "/* %s */ .%schroma .%s:last-child { width: 100%%; }",
|
||||
chroma.LineTableTD, f.prefix, f.class(chroma.LineTableTD)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// Special-case line number highlighting when targeted.
|
||||
if f.lineNumbers || f.lineNumbersInTable {
|
||||
targetedLineCSS := StyleEntryToCSS(style.Get(chroma.LineHighlight))
|
||||
for _, tt := range []chroma.TokenType{chroma.LineNumbers, chroma.LineNumbersTable} {
|
||||
fmt.Fprintf(w, "/* %s targeted by URL anchor */ .%schroma .%s:target { %s }\n", tt, f.prefix, f.class(tt), targetedLineCSS)
|
||||
}
|
||||
}
|
||||
tts := []int{}
|
||||
for tt := range css {
|
||||
tts = append(tts, int(tt))
|
||||
}
|
||||
sort.Ints(tts)
|
||||
for _, ti := range tts {
|
||||
tt := chroma.TokenType(ti)
|
||||
if tt == chroma.Background {
|
||||
continue
|
||||
}
|
||||
styles := css[tt]
|
||||
if _, err := fmt.Fprintf(w, "/* %s */ .%schroma .%s { %s }\n", tt, f.prefix, f.class(tt), styles); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Formatter) styleToCSS(style *chroma.Style) map[chroma.TokenType]string {
|
||||
classes := map[chroma.TokenType]string{}
|
||||
bg := style.Get(chroma.Background)
|
||||
// Convert the style.
|
||||
for t := range chroma.StandardTypes {
|
||||
entry := style.Get(t)
|
||||
if t != chroma.Background {
|
||||
entry = entry.Sub(bg)
|
||||
}
|
||||
if entry.IsZero() {
|
||||
continue
|
||||
}
|
||||
classes[t] = StyleEntryToCSS(entry)
|
||||
}
|
||||
classes[chroma.Background] += f.tabWidthStyle()
|
||||
lineNumbersStyle := "margin-right: 0.4em; padding: 0 0.4em 0 0.4em;"
|
||||
// All rules begin with default rules followed by user provided rules
|
||||
classes[chroma.LineNumbers] = lineNumbersStyle + classes[chroma.LineNumbers]
|
||||
classes[chroma.LineNumbersTable] = lineNumbersStyle + classes[chroma.LineNumbersTable]
|
||||
classes[chroma.LineHighlight] = "display: block; width: 100%;" + classes[chroma.LineHighlight]
|
||||
classes[chroma.LineTable] = "border-spacing: 0; padding: 0; margin: 0; border: 0; width: auto; overflow: auto; display: block;" + classes[chroma.LineTable]
|
||||
classes[chroma.LineTableTD] = "vertical-align: top; padding: 0; margin: 0; border: 0;" + classes[chroma.LineTableTD]
|
||||
return classes
|
||||
}
|
||||
|
||||
// StyleEntryToCSS converts a chroma.StyleEntry to CSS attributes.
|
||||
func StyleEntryToCSS(e chroma.StyleEntry) string {
|
||||
styles := []string{}
|
||||
if e.Colour.IsSet() {
|
||||
styles = append(styles, "color: "+e.Colour.String())
|
||||
}
|
||||
if e.Background.IsSet() {
|
||||
styles = append(styles, "background-color: "+e.Background.String())
|
||||
}
|
||||
if e.Bold == chroma.Yes {
|
||||
styles = append(styles, "font-weight: bold")
|
||||
}
|
||||
if e.Italic == chroma.Yes {
|
||||
styles = append(styles, "font-style: italic")
|
||||
}
|
||||
if e.Underline == chroma.Yes {
|
||||
styles = append(styles, "text-decoration: underline")
|
||||
}
|
||||
return strings.Join(styles, "; ")
|
||||
}
|
||||
|
||||
// Compress CSS attributes - remove spaces, transform 6-digit colours to 3.
|
||||
func compressStyle(s string) string {
|
||||
parts := strings.Split(s, ";")
|
||||
out := []string{}
|
||||
for _, p := range parts {
|
||||
p = strings.Join(strings.Fields(p), " ")
|
||||
p = strings.Replace(p, ": ", ":", 1)
|
||||
if strings.Contains(p, "#") {
|
||||
c := p[len(p)-6:]
|
||||
if c[0] == c[1] && c[2] == c[3] && c[4] == c[5] {
|
||||
p = p[:len(p)-6] + c[0:1] + c[2:3] + c[4:5]
|
||||
}
|
||||
}
|
||||
out = append(out, p)
|
||||
}
|
||||
return strings.Join(out, ";")
|
||||
}
|
31
vendor/github.com/alecthomas/chroma/formatters/json.go
generated
vendored
31
vendor/github.com/alecthomas/chroma/formatters/json.go
generated
vendored
@ -1,31 +0,0 @@
|
||||
package formatters
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/alecthomas/chroma"
|
||||
)
|
||||
|
||||
// JSON formatter outputs the raw token structures as JSON.
|
||||
var JSON = Register("json", chroma.FormatterFunc(func(w io.Writer, s *chroma.Style, it chroma.Iterator) error {
|
||||
fmt.Fprintln(w, "[")
|
||||
i := 0
|
||||
for t := it(); t != chroma.EOF; t = it() {
|
||||
if i > 0 {
|
||||
fmt.Fprintln(w, ",")
|
||||
}
|
||||
i++
|
||||
bytes, err := json.Marshal(t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, " "+string(bytes)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
fmt.Fprintln(w)
|
||||
fmt.Fprintln(w, "]")
|
||||
return nil
|
||||
}))
|
51
vendor/github.com/alecthomas/chroma/formatters/svg/font_liberation_mono.go
generated
vendored
51
vendor/github.com/alecthomas/chroma/formatters/svg/font_liberation_mono.go
generated
vendored
File diff suppressed because one or more lines are too long
222
vendor/github.com/alecthomas/chroma/formatters/svg/svg.go
generated
vendored
222
vendor/github.com/alecthomas/chroma/formatters/svg/svg.go
generated
vendored
@ -1,222 +0,0 @@
|
||||
// Package svg contains an SVG formatter.
|
||||
package svg
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/chroma"
|
||||
)
|
||||
|
||||
// Option sets an option of the SVG formatter.
|
||||
type Option func(f *Formatter)
|
||||
|
||||
// FontFamily sets the font-family.
|
||||
func FontFamily(fontFamily string) Option { return func(f *Formatter) { f.fontFamily = fontFamily } }
|
||||
|
||||
// EmbedFontFile embeds given font file
|
||||
func EmbedFontFile(fontFamily string, fileName string) (option Option, err error) {
|
||||
var format FontFormat
|
||||
switch path.Ext(fileName) {
|
||||
case ".woff":
|
||||
format = WOFF
|
||||
case ".woff2":
|
||||
format = WOFF2
|
||||
case ".ttf":
|
||||
format = TRUETYPE
|
||||
default:
|
||||
return nil, errors.New("unexpected font file suffix")
|
||||
}
|
||||
|
||||
var content []byte
|
||||
if content, err = ioutil.ReadFile(fileName); err == nil {
|
||||
option = EmbedFont(fontFamily, base64.StdEncoding.EncodeToString(content), format)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// EmbedFont embeds given base64 encoded font
|
||||
func EmbedFont(fontFamily string, font string, format FontFormat) Option {
|
||||
return func(f *Formatter) { f.fontFamily = fontFamily; f.embeddedFont = font; f.fontFormat = format }
|
||||