├── testdata
├── 1
│ ├── static
│ │ ├── pending.png
│ │ ├── boxcniB7OYCR0mmRx0kBAcfbZmc.jpg
│ │ ├── boxcnx060XAN4NUm2doWRuGToWr.jpg
│ │ └── boxcnyAEhNeanmSz2XhcK7ata0t.jpg
│ ├── data.md
│ └── data.json
└── 2
│ ├── static
│ ├── boxcn0HzjG37SyTpjU1yZf0KqPD.jpg
│ ├── boxcn25PWN2On2MLOY5BWG7z1Hg.jpg
│ ├── boxcn3lEjzi1dtjcW0HefP4S7xf.jpg
│ ├── boxcn3xaJFpBpeHu6pAmWzOrtje.jpg
│ ├── boxcn40Y8XbPNrVWhXFGVRLmbme.jpg
│ ├── boxcn4wmVZNhV3lZkLjmGKZc5Md.jpg
│ ├── boxcn5lChHrJaszJIyXnlgaz6Xg.jpg
│ ├── boxcn6Vrm09Vc8VRZOJbWhTIigd.jpg
│ ├── boxcn7ZWNAdXvg4UZbLWqBJf2yh.jpg
│ ├── boxcn8OMM3d3GRkIgwnHc1hSCjh.jpg
│ ├── boxcnADb2YDHqZm37TEACF98LtI.jpg
│ ├── boxcnAHohD8jQYdeMYJMdeuZxkc.jpg
│ ├── boxcnARhtVIowNIXDwo5QjFZnmh.jpg
│ ├── boxcnC2Eg3D9X61sqbaJPB3Kp2f.jpg
│ ├── boxcnCiUW4Qo1p2Qc6hfXo96VAe.jpg
│ ├── boxcnFxR4HoSuuzrk6RYCVzCBOg.jpg
│ ├── boxcnFyq7S9MamZsL36LGcOgOQe.jpg
│ ├── boxcnGNXYmjel1Z2XoVRxK4kt6g.jpg
│ ├── boxcnHQ1vvmYL22k9uKq5rkKZFb.jpg
│ ├── boxcnJg137wnmKcJ5BgDDnfgQ2n.jpg
│ ├── boxcnKwIOri3Lt1DmnoKDbxIoBd.jpg
│ ├── boxcnPevppqdMDOuENHwQ39NLQ0.jpg
│ ├── boxcnU4jh8M4Je3HH9hkrm8Ouvg.jpg
│ ├── boxcnYiBn8uesGTe4ZOmwXqhmOc.jpg
│ ├── boxcnZd087QeiMwEXhESnXKsaGh.jpg
│ ├── boxcna1WNPAzBk8jMDm7fgLDUah.jpg
│ ├── boxcna7jKR0D2waFy8b1h1Mn9sh.jpg
│ ├── boxcnfUN5uriCMTVxhTO3JUIgmf.jpg
│ ├── boxcng4vXnqf40s8biMrNZJIyHg.jpg
│ ├── boxcnhRvghde8oV88siXY6HEJdb.jpg
│ ├── boxcnj0jnTpqsT2psX4PjN7RdUc.jpg
│ ├── boxcnkpN3TF5YXEVjpbgJ48gzQb.jpg
│ ├── boxcnmheXItwGdTJR6YY3VCmWlb.jpg
│ ├── boxcnn8lcAoQJkdADTdsktG3uhj.jpg
│ ├── boxcnni357jaooOc8dyVZgwOT0f.jpg
│ ├── boxcnoEPle5mVh1MCEOAeCd78Kg.jpg
│ ├── boxcnoL6TtwSadFAq0JdJyQQ8Rg.jpg
│ ├── boxcnoVfyT94NXsCjur6xnLGEfb.jpg
│ ├── boxcnqYLIQq0QByyf3UvEWc0jug.jpg
│ ├── boxcnunibrea2QMPlGTnUYyK9dh.jpg
│ ├── boxcnvy8YGoxrsZiEB3OuOtV76e.jpg
│ ├── boxcnwIP4hJADL0BfDkiO0EJcQ9.jpg
│ ├── boxcnwl8p1SpMmjVjdDXcmQtRfd.jpg
│ └── boxcnzb83lR9jSX5BQZlYIkvVac.jpg
│ └── data.md
├── .gitignore
├── go.mod
├── .github
├── test.sh
├── dependabot.yml
└── workflows
│ ├── release.yml
│ ├── codestyle-check.yml
│ ├── test.yml
│ └── codeql-analysis.yml
├── .goreleaser.yml
├── _examples
└── main.go
├── static.go
├── go.sum
├── README.md
├── md_test.go
├── md.go
└── LICENSE
/testdata/1/static/pending.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/1/static/pending.png
--------------------------------------------------------------------------------
/testdata/1/static/boxcniB7OYCR0mmRx0kBAcfbZmc.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/1/static/boxcniB7OYCR0mmRx0kBAcfbZmc.jpg
--------------------------------------------------------------------------------
/testdata/1/static/boxcnx060XAN4NUm2doWRuGToWr.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/1/static/boxcnx060XAN4NUm2doWRuGToWr.jpg
--------------------------------------------------------------------------------
/testdata/1/static/boxcnyAEhNeanmSz2XhcK7ata0t.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/1/static/boxcnyAEhNeanmSz2XhcK7ata0t.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcn0HzjG37SyTpjU1yZf0KqPD.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcn0HzjG37SyTpjU1yZf0KqPD.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcn25PWN2On2MLOY5BWG7z1Hg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcn25PWN2On2MLOY5BWG7z1Hg.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcn3lEjzi1dtjcW0HefP4S7xf.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcn3lEjzi1dtjcW0HefP4S7xf.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcn3xaJFpBpeHu6pAmWzOrtje.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcn3xaJFpBpeHu6pAmWzOrtje.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcn40Y8XbPNrVWhXFGVRLmbme.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcn40Y8XbPNrVWhXFGVRLmbme.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcn4wmVZNhV3lZkLjmGKZc5Md.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcn4wmVZNhV3lZkLjmGKZc5Md.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcn5lChHrJaszJIyXnlgaz6Xg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcn5lChHrJaszJIyXnlgaz6Xg.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcn6Vrm09Vc8VRZOJbWhTIigd.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcn6Vrm09Vc8VRZOJbWhTIigd.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcn7ZWNAdXvg4UZbLWqBJf2yh.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcn7ZWNAdXvg4UZbLWqBJf2yh.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcn8OMM3d3GRkIgwnHc1hSCjh.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcn8OMM3d3GRkIgwnHc1hSCjh.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnADb2YDHqZm37TEACF98LtI.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnADb2YDHqZm37TEACF98LtI.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnAHohD8jQYdeMYJMdeuZxkc.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnAHohD8jQYdeMYJMdeuZxkc.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnARhtVIowNIXDwo5QjFZnmh.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnARhtVIowNIXDwo5QjFZnmh.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnC2Eg3D9X61sqbaJPB3Kp2f.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnC2Eg3D9X61sqbaJPB3Kp2f.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnCiUW4Qo1p2Qc6hfXo96VAe.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnCiUW4Qo1p2Qc6hfXo96VAe.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnFxR4HoSuuzrk6RYCVzCBOg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnFxR4HoSuuzrk6RYCVzCBOg.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnFyq7S9MamZsL36LGcOgOQe.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnFyq7S9MamZsL36LGcOgOQe.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnGNXYmjel1Z2XoVRxK4kt6g.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnGNXYmjel1Z2XoVRxK4kt6g.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnHQ1vvmYL22k9uKq5rkKZFb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnHQ1vvmYL22k9uKq5rkKZFb.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnJg137wnmKcJ5BgDDnfgQ2n.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnJg137wnmKcJ5BgDDnfgQ2n.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnKwIOri3Lt1DmnoKDbxIoBd.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnKwIOri3Lt1DmnoKDbxIoBd.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnPevppqdMDOuENHwQ39NLQ0.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnPevppqdMDOuENHwQ39NLQ0.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnU4jh8M4Je3HH9hkrm8Ouvg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnU4jh8M4Je3HH9hkrm8Ouvg.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnYiBn8uesGTe4ZOmwXqhmOc.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnYiBn8uesGTe4ZOmwXqhmOc.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnZd087QeiMwEXhESnXKsaGh.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnZd087QeiMwEXhESnXKsaGh.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcna1WNPAzBk8jMDm7fgLDUah.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcna1WNPAzBk8jMDm7fgLDUah.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcna7jKR0D2waFy8b1h1Mn9sh.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcna7jKR0D2waFy8b1h1Mn9sh.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnfUN5uriCMTVxhTO3JUIgmf.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnfUN5uriCMTVxhTO3JUIgmf.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcng4vXnqf40s8biMrNZJIyHg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcng4vXnqf40s8biMrNZJIyHg.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnhRvghde8oV88siXY6HEJdb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnhRvghde8oV88siXY6HEJdb.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnj0jnTpqsT2psX4PjN7RdUc.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnj0jnTpqsT2psX4PjN7RdUc.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnkpN3TF5YXEVjpbgJ48gzQb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnkpN3TF5YXEVjpbgJ48gzQb.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnmheXItwGdTJR6YY3VCmWlb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnmheXItwGdTJR6YY3VCmWlb.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnn8lcAoQJkdADTdsktG3uhj.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnn8lcAoQJkdADTdsktG3uhj.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnni357jaooOc8dyVZgwOT0f.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnni357jaooOc8dyVZgwOT0f.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnoEPle5mVh1MCEOAeCd78Kg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnoEPle5mVh1MCEOAeCd78Kg.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnoL6TtwSadFAq0JdJyQQ8Rg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnoL6TtwSadFAq0JdJyQQ8Rg.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnoVfyT94NXsCjur6xnLGEfb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnoVfyT94NXsCjur6xnLGEfb.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnqYLIQq0QByyf3UvEWc0jug.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnqYLIQq0QByyf3UvEWc0jug.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnunibrea2QMPlGTnUYyK9dh.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnunibrea2QMPlGTnUYyK9dh.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnvy8YGoxrsZiEB3OuOtV76e.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnvy8YGoxrsZiEB3OuOtV76e.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnwIP4hJADL0BfDkiO0EJcQ9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnwIP4hJADL0BfDkiO0EJcQ9.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnwl8p1SpMmjVjdDXcmQtRfd.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnwl8p1SpMmjVjdDXcmQtRfd.jpg
--------------------------------------------------------------------------------
/testdata/2/static/boxcnzb83lR9jSX5BQZlYIkvVac.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chyroc/lark_docs_md/HEAD/testdata/2/static/boxcnzb83lR9jSX5BQZlYIkvVac.jpg
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Binaries for programs and plugins
2 | *.exe
3 | *.exe~
4 | *.dll
5 | *.so
6 | *.dylib
7 |
8 | # Test binary, built with `go test -c`
9 | *.test
10 |
11 | # Output of the go coverage tool, specifically when used with LiteIDE
12 | *.out
13 |
14 | # Dependency directories (remove the comment below to include it)
15 | # vendor/
16 |
17 | .idea/
18 | ttt/
19 | coverage.txt
20 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/chyroc/lark_docs_md
2 |
3 | go 1.17
4 |
5 | require (
6 | github.com/chyroc/lark v0.0.106
7 | github.com/stretchr/testify v1.8.1
8 | )
9 |
10 | require (
11 | github.com/chyroc/go-ptr v1.7.0 // indirect
12 | github.com/davecgh/go-spew v1.1.1 // indirect
13 | github.com/pmezard/go-difflib v1.0.0 // indirect
14 | gopkg.in/yaml.v3 v3.0.1 // indirect
15 | )
16 |
--------------------------------------------------------------------------------
/.github/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | module_name=$(cat go.mod | grep module | cut -d ' ' -f 2-2)
6 | echo "module_name is $module_name"
7 |
8 | GO111MODULE=on echo 'mode: atomic' > coverage.txt && \
9 | go list ./... | \
10 | xargs -n1 -I{} sh -c 'LOCAL_TEST=true go test -covermode=atomic -coverprofile=coverage.tmp -coverpkg=./... -parallel 1 -p 1 -count=1 -gcflags=-l {} && tail -n +2 coverage.tmp >> coverage.txt' && \
11 | rm coverage.tmp
12 |
13 | # go tool cover -func=coverage.txt -o coverage.txt
14 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: "gomod" # See documentation for possible values
9 | directory: "/" # Location of package manifests
10 | schedule:
11 | interval: "daily"
12 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: goreleaser
2 |
3 | on:
4 | push:
5 | tags:
6 | - '*'
7 |
8 | jobs:
9 | goreleaser:
10 | runs-on: ubuntu-latest
11 | steps:
12 | -
13 | name: Checkout
14 | uses: actions/checkout@v2
15 | with:
16 | fetch-depth: 0
17 | -
18 | name: Set up Go
19 | uses: actions/setup-go@v2
20 | with:
21 | go-version: 1.16
22 | -
23 | name: Run GoReleaser
24 | uses: goreleaser/goreleaser-action@v2
25 | with:
26 | version: latest
27 | args: release --rm-dist
28 | env:
29 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
--------------------------------------------------------------------------------
/.goreleaser.yml:
--------------------------------------------------------------------------------
1 | # docs: http://goreleaser.com
2 | before:
3 | hooks:
4 | - go mod download
5 | builds:
6 | - env:
7 | - CGO_ENABLED=0
8 | goos:
9 | - linux
10 | - windows
11 | - darwin
12 | main: ./cmd/incr
13 | archives:
14 | - replacements:
15 | darwin: Darwin
16 | linux: Linux
17 | windows: Windows
18 | 386: i386
19 | amd64: x86_64
20 | checksum:
21 | name_template: 'checksums.txt'
22 | snapshot:
23 | name_template: "{{ .Tag }}-next"
24 | changelog:
25 | sort: asc
26 | filters:
27 | exclude:
28 | - '^docs:'
29 | - '^test:'
30 | source:
31 | enabled: true
32 | name_template: "{{.ProjectName}}-{{.Version}}"
33 |
--------------------------------------------------------------------------------
/.github/workflows/codestyle-check.yml:
--------------------------------------------------------------------------------
1 | name: codestyle-check
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 | schedule:
9 | - cron: "0 0 * * *"
10 |
11 | jobs:
12 |
13 | run:
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/checkout@v2
17 |
18 | - name: Set up Go
19 | uses: actions/setup-go@v2
20 | with:
21 | go-version: 1.17
22 |
23 | - name: Set up Check Tool
24 | run: |
25 | go get -u github.com/client9/misspell/cmd/misspell
26 |
27 | - name: Code Style Check
28 | run: |
29 | ls -alh
30 | go build -v ./...
31 | gofmt -s
32 | go vet ./...
33 | misspell -error
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: go-test
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | jobs:
10 |
11 | run:
12 | runs-on: ubuntu-latest
13 | timeout-minutes: 30
14 | steps:
15 | - uses: actions/checkout@v2
16 |
17 | - name: Set up Go
18 | uses: actions/setup-go@v2
19 | with:
20 | go-version: 1.17
21 |
22 | - name: Build
23 | run: go build -v ./...
24 |
25 | - name: Test
26 | run: |
27 | export IN_CI=1
28 | ./.github/test.sh
29 | env:
30 | LARK_CHYROC_HEYMAN_APP_ID: ${{ secrets.LARK_CHYROC_HEYMAN_APP_ID }}
31 | LARK_CHYROC_HEYMAN_APP_SECRET: ${{ secrets.LARK_CHYROC_HEYMAN_APP_SECRET }}
32 |
33 | - name: Upload Cov
34 | run: bash <(curl -s https://codecov.io/bash)
35 |
--------------------------------------------------------------------------------
/_examples/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 |
7 | "github.com/chyroc/lark"
8 | "github.com/chyroc/lark/larkext"
9 | "github.com/chyroc/lark_docs_md"
10 | )
11 |
12 | func main() {
13 | larkClient := lark.New(lark.WithAppCredential("app-id", "app-secret"))
14 | docToken := "doc-token"
15 |
16 | // 这一步是获取 doc 内容
17 | doc, err := larkext.NewDoc(larkClient, docToken).Content(context.Background())
18 | if err != nil {
19 | panic(err)
20 | }
21 |
22 | // 转化为 markdown
23 | result := lark_docs_md.DocMarkdown(context.Background(), doc, &lark_docs_md.FormatOpt{
24 | LarkClient: larkClient,
25 |
26 | // 如果需要下载图片等静态文件,请配置这两项
27 | // StaticDir: "static",
28 | // FilePrefix: "static",
29 |
30 | // 如果不需要下载文件,而替换为 24 小时有效的链接,请配置这个项
31 | StaticAsURL: true,
32 | })
33 |
34 | // 输出
35 | fmt.Println(result)
36 | }
37 |
--------------------------------------------------------------------------------
/static.go:
--------------------------------------------------------------------------------
1 | package lark_docs_md
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "io"
7 | "log"
8 | "os"
9 | "path/filepath"
10 |
11 | "github.com/chyroc/lark"
12 | )
13 |
14 | func downloadFile(ctx context.Context, fileToken, name string, opt *FormatOpt) string {
15 | if opt.LarkClient == nil {
16 | return ""
17 | }
18 | if opt.StaticAsURL {
19 | resp, _, err := opt.LarkClient.Drive.BatchGetDriveMediaTmpDownloadURL(ctx, &lark.BatchGetDriveMediaTmpDownloadURLReq{
20 | FileTokens: []string{fileToken},
21 | })
22 | if err != nil {
23 | log.Printf("lark get drive media tmp url %s fail: %s", fileToken, err)
24 | return ""
25 | }
26 | for _, v := range resp.TmpDownloadURLs {
27 | return v.TmpDownloadURL
28 | }
29 | return ""
30 | } else {
31 | resp, _, err := opt.LarkClient.Drive.DownloadDriveMedia(ctx, &lark.DownloadDriveMediaReq{
32 | FileToken: fileToken,
33 | })
34 | if err != nil {
35 | log.Printf("lark download drive media %s fail: %s", fileToken, err)
36 | return ""
37 | }
38 | filename := fmt.Sprintf("%s/%s", opt.StaticDir, name)
39 | mdname := fmt.Sprintf("%s/%s", opt.FilePrefix, name)
40 | _ = os.MkdirAll(filepath.Dir(filename), 0o755)
41 | f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0o666)
42 | if err != nil {
43 | log.Printf("open file %s fail: %s", filename, err)
44 | return ""
45 | }
46 | defer f.Close()
47 |
48 | _, _ = io.Copy(f, resp.File)
49 | return mdname
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/chyroc/go-ptr v1.7.0 h1:wwm53+SeMvpQbBcsZviNPlz2djpxyELjVOZFHtUjHho=
2 | github.com/chyroc/go-ptr v1.7.0/go.mod h1:+AAlVrPed1XbNyqZ7r/J3o79V1awCvd5wrYkxu8tsow=
3 | github.com/chyroc/lark v0.0.106 h1:zU3bCqDROLU5t25SJKCBXY8tDZE+ANAElZhokC7jDOQ=
4 | github.com/chyroc/lark v0.0.106/go.mod h1:iYv0NXuCzYeypk1eY9Mos6QP7CQuLK7YH3Oxi09p7NU=
5 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
7 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
8 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
9 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
10 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
11 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
12 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
13 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
14 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
15 | github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
16 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
17 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
18 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
19 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
20 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
21 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # lark_docs_md
2 |
3 | [](https://codecov.io/gh/chyroc/lark_docs_md)
4 | [](https://goreportcard.com/report/github.com/chyroc/lark_docs_md)
5 | [](https://github.com/chyroc/lark_docs_md/actions)
6 | [](https://opensource.org/licenses/Apache-2.0)
7 | [](https://pkg.go.dev/github.com/chyroc/lark_docs_md)
8 | [](https://badge.fury.io/go/github.com%2Fchyroc%2Flark_docs_md)
9 |
10 | 
11 |
12 | ## Install
13 |
14 | ```shell
15 | go get github.com/chyroc/lark_docs_md
16 | ```
17 |
18 | ## Usage
19 |
20 | ```go
21 | package main
22 |
23 | import (
24 | "context"
25 | "fmt"
26 |
27 | "github.com/chyroc/lark"
28 | "github.com/chyroc/lark/larkext"
29 | "github.com/chyroc/lark_docs_md"
30 | )
31 |
32 | func main() {
33 | larkClient := lark.New(lark.WithAppCredential("app-id", "app-secret"))
34 | docToken := "doc-token"
35 |
36 | // 这一步是获取 doc 内容
37 | doc, err := larkext.NewDoc(larkClient, docToken).Content(context.Background())
38 | if err != nil {
39 | panic(err)
40 | }
41 |
42 | // 转化为 markdown
43 | result := lark_docs_md.DocMarkdown(context.Background(), doc, &lark_docs_md.FormatOpt{
44 | LarkClient: larkClient,
45 |
46 | // 如果需要下载图片等静态文件,请配置这两项
47 | // StaticDir: "static",
48 | // FilePrefix: "static",
49 |
50 | // 如果不需要下载文件,而替换为 24 小时有效的链接,请配置这个项
51 | StaticAsURL: true,
52 | })
53 |
54 | // 输出
55 | fmt.Println(result)
56 | }
57 | ```
58 |
--------------------------------------------------------------------------------
/testdata/1/data.md:
--------------------------------------------------------------------------------
1 | # 📔 这是一个飞书文档的例子
2 |
3 | > 这是一个飞书文档的例子,包含所有 Markdown 支持的语法
4 |
5 | # 标题
6 |
7 | ## 二级标题
8 |
9 | ### 三级标题
10 |
11 | #### 四级标题
12 |
13 | ##### 五级标题
14 |
15 | ###### 六级标题
16 |
17 | # 正文
18 |
19 | 正文,这是正文,这个是正文,这个是正文啊。
20 | 正文,这是正文,这个是正文,这个是正文啊。正文,这是正文,这个是正文,这个是正文啊。正文,这是正文,这个是正文,这个是正文啊。正文,这是正文,这个是正文,这个是正文啊。正文,这是正文,这个是正文,这个是正文啊。正文,这是正文,这个是正文,这个是正文啊。正文,这是正文,这个是正文,这个是正文啊。
21 | # 列表
22 |
23 | ## 有序列表
24 |
25 | 1. 1
26 | 1. A
27 | 1. i
28 | 1. 1
29 | 1. a
30 | 2. b
31 | 3. X
32 | 2. 2
33 | 3. 3
34 | 2. Ii
35 | 3. Iii
36 | 4. iv
37 | 5. Dd
38 | 2. B
39 | 3. C
40 | 4. D
41 | 5. E
42 | 6. F
43 | 7. G
44 | 2. 2
45 | 3. 3
46 | ## 无序列表
47 |
48 | - X
49 | - XX
50 | - XXX
51 | - XXX
52 | - XXXX
53 | - X
54 | - X
55 | # 任务列表
56 |
57 | - [ ] 任务 x
58 | - [ ] 任务 xx
59 | - [ ] 任务 x
60 | - [x] 完成的任务 x
61 | # 高亮块
62 |
63 | ```
64 | 高亮块
65 |
66 | 高亮块支持颜色,转成 Markdown 后不支持
67 |
68 | ```
69 | # 分割线
70 |
71 |
72 | ---
73 |
74 | # 引用
75 |
76 | > 这是一个引用
77 |
78 | > 这是一个引用,有 tab
79 |
80 | > 引用行 1
81 | > 引用行 2
82 | > 引用行 3
83 |
84 | # 代码块
85 |
86 | ```Go
87 | func f() {
88 | // do sth
89 | }
90 |
91 | ```
92 | # 图片
93 |
94 | ## 一个图片
95 |
96 |
97 | ## 并排图片
98 |
99 | 
100 |
101 | # 表格
102 |
103 |
104 | # 电子表格
105 |
106 | `[sheet: shtcnVZBJ1F05uW16LwcibZDJdf_8OPm5F]`
107 | # 链接
108 |
109 | [链接文本](https%3A%2F%2Fply.readthedocs.io%2Fen%2Flatest%2Fply.html)
110 | # 网页卡片
111 |
112 | `[undefined-block]`
113 | # 云文档
114 |
115 | [云文档](https://rs6qnacjws.feishu.cn/docs/doccnKOgFFoPz5Z1OZ5wU9H7sdf)
116 | # 群名片
117 |
118 | `[chat: oc_e5dc4d726035aff7317c168440ed5b5b]`
119 | # 文件
120 |
121 | [file: pending.png](static/pending.png)
122 |
123 |
--------------------------------------------------------------------------------
/md_test.go:
--------------------------------------------------------------------------------
1 | package lark_docs_md_test
2 |
3 | import (
4 | "context"
5 | "encoding/json"
6 | "fmt"
7 | "io/ioutil"
8 | "os"
9 | "testing"
10 | "time"
11 |
12 | "github.com/chyroc/lark"
13 | "github.com/chyroc/lark/larkext"
14 | "github.com/chyroc/lark_docs_md"
15 | "github.com/stretchr/testify/assert"
16 | )
17 |
18 | func TestDocMarkdown(t *testing.T) {
19 | as := assert.New(t)
20 | larkClient := lark.New(
21 | lark.WithAppCredential(os.Getenv("LARK_CHYROC_HEYMAN_APP_ID"), os.Getenv("LARK_CHYROC_HEYMAN_APP_SECRET")),
22 | lark.WithTimeout(time.Minute),
23 | )
24 |
25 | tests := []struct {
26 | name string
27 | }{
28 | {"1"},
29 | {"2"},
30 | }
31 | for _, tt := range tests {
32 | t.Run(tt.name, func(t *testing.T) {
33 | opt := &lark_docs_md.FormatOpt{
34 | LarkClient: larkClient,
35 | StaticDir: fmt.Sprintf("testdata/%s/static", tt.name),
36 | FilePrefix: "static",
37 | }
38 |
39 | doc := loadDocContent(t, tt.name)
40 | md := loadMarkdown(t, tt.name)
41 | result := lark_docs_md.DocMarkdown(context.Background(), doc, opt)
42 | as.Equal(md, result, tt.name)
43 | })
44 | }
45 | }
46 |
47 | func Test_FromDocToken(t *testing.T) {
48 | t.Skip()
49 |
50 | as := assert.New(t)
51 |
52 | // https://rs6qnacjws.feishu.cn/docs/doccng7C51ULsOrHtbmWBa3a4Hf
53 | larkClient := lark.New(
54 | lark.WithAppCredential(os.Getenv("LARK_CHYROC_HEYMAN_APP_ID"), os.Getenv("LARK_CHYROC_HEYMAN_APP_SECRET")),
55 | )
56 | docToken := "doccng7C51ULsOrHtbmWBa3a4Hf"
57 |
58 | doc, err := larkext.NewDoc(larkClient, docToken).Content(context.Background())
59 | as.Nil(err)
60 |
61 | result := lark_docs_md.DocMarkdown(context.Background(), doc, &lark_docs_md.FormatOpt{
62 | LarkClient: larkClient,
63 | // StaticDir: "/tmp/tmp-static",
64 | // FilePrefix: "static",
65 | StaticAsURL: true,
66 | })
67 | fmt.Println(result)
68 | }
69 |
70 | func loadDocContent(t *testing.T, testCase string) *lark.DocContent {
71 | as := assert.New(t)
72 |
73 | bs, err := ioutil.ReadFile(fmt.Sprintf("testdata/%s/data.json", testCase))
74 | as.Nil(err)
75 |
76 | doc := &lark.DocContent{}
77 | as.Nil(json.Unmarshal(bs, doc))
78 |
79 | return doc
80 | }
81 |
82 | func loadMarkdown(t *testing.T, testCase string) string {
83 | as := assert.New(t)
84 |
85 | bs, err := ioutil.ReadFile(fmt.Sprintf("testdata/%s/data.md", testCase))
86 | as.Nil(err)
87 |
88 | return string(bs)
89 | }
90 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "codeql-analtsis"
13 |
14 | on:
15 | push:
16 | branches: [ master ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ master ]
20 | schedule:
21 | - cron: '39 15 * * 6'
22 |
23 | jobs:
24 | run:
25 | runs-on: ubuntu-latest
26 | permissions:
27 | actions: read
28 | contents: read
29 | security-events: write
30 |
31 | strategy:
32 | fail-fast: false
33 | matrix:
34 | language: [ 'go' ]
35 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
36 | # Learn more:
37 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
38 |
39 | steps:
40 | - name: Checkout repository
41 | uses: actions/checkout@v2
42 |
43 | # Initializes the CodeQL tools for scanning.
44 | - name: Initialize CodeQL
45 | uses: github/codeql-action/init@v1
46 | with:
47 | languages: ${{ matrix.language }}
48 | # If you wish to specify custom queries, you can do so here or in a config file.
49 | # By default, queries listed here will override any specified in a config file.
50 | # Prefix the list here with "+" to use these queries and those in the config file.
51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
52 |
53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
54 | # If this step fails, then you should remove it and run the build manually (see below)
55 | - name: Autobuild
56 | uses: github/codeql-action/autobuild@v1
57 |
58 | # ℹ️ Command-line programs to run using the OS shell.
59 | # 📚 https://git.io/JvXDl
60 |
61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
62 | # and modify them (or add more) to build your code if your project
63 | # uses a compiled language
64 |
65 | #- run: |
66 | # make bootstrap
67 | # make release
68 |
69 | - name: Perform CodeQL Analysis
70 | uses: github/codeql-action/analyze@v1
71 |
--------------------------------------------------------------------------------
/md.go:
--------------------------------------------------------------------------------
1 | package lark_docs_md
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "strings"
7 |
8 | "github.com/chyroc/lark"
9 | )
10 |
11 | type FormatOpt struct {
12 | ctx context.Context
13 | LarkClient *lark.Lark // lark 客户端
14 | StaticDir string // 如果需要下载静态文件,那么需要指定静态文件的目录
15 | FilePrefix string // 针对静态文件,需要指定文件在 Markdown 中的前缀
16 | StaticAsURL bool // 不下载静态文件,直接把静态文件的 URL 插入到 Markdown 中
17 | }
18 |
19 | func DocMarkdown(ctx context.Context, doc *lark.DocContent, opt *FormatOpt) string {
20 | if opt == nil {
21 | opt = new(FormatOpt)
22 | }
23 | opt.ctx = ctx
24 | if opt.StaticDir == "" {
25 | opt.StaticDir = "static"
26 | }
27 | if opt.FilePrefix == "" {
28 | opt.FilePrefix = "static"
29 | }
30 |
31 | buf := new(strings.Builder)
32 |
33 | buf.WriteString("# ")
34 | buf.WriteString(DocParagraphMarkdown(doc.Title, opt))
35 | buf.WriteString("\n\n")
36 |
37 | buf.WriteString(DocBodyMarkdown(doc.Body, opt))
38 |
39 | return buf.String()
40 | }
41 |
42 | func DocBodyMarkdown(r *lark.DocBody, opt *FormatOpt) string {
43 | buf := new(strings.Builder)
44 |
45 | for idx, v := range r.Blocks {
46 | buf.WriteString(DocBlockMarkdown(v, opt))
47 | buf.WriteString("\n")
48 |
49 | // 如果 v 是 list,并且是最后一个,那么需要换行
50 | if idx == len(r.Blocks)-1 && v.Type == lark.DocBlockTypeParagraph && v.Paragraph.Style != nil && v.Paragraph.Style.List != nil && v.Paragraph.Style.List.IndentLevel > 0 {
51 | buf.WriteString("\n")
52 | }
53 | }
54 |
55 | return buf.String()
56 | }
57 |
58 | func DocBlockMarkdown(r *lark.DocBlock, opt *FormatOpt) string {
59 | switch r.Type {
60 | case "paragraph":
61 | return DocParagraphMarkdown(r.Paragraph, opt)
62 | case "gallery":
63 | return DocGalleryMarkdown(r.Gallery, opt)
64 | case "file":
65 | return DocFileMarkdown(r.File, opt)
66 | case "chatGroup":
67 | return DocChatGroupMarkdown(r.ChatGroup, opt)
68 | case "table":
69 | return DocTableMarkdown(r.Table, opt)
70 | case "horizontalLine":
71 | return DocHorizontalLineMarkdown(r.HorizontalLine, opt)
72 | case "embeddedPage":
73 | return DocEmbeddedPageMarkdown(r.EmbeddedPage, opt)
74 | case "sheet":
75 | return DocSheetMarkdown(r.Sheet, opt)
76 | case "bitable":
77 | return DocBitableMarkdown(r.Bitable, opt)
78 | case "diagram":
79 | return DocDiagramMarkdown(r.Diagram, opt)
80 | case "jira":
81 | return DocJiraMarkdown(r.Jira, opt)
82 | case "poll":
83 | return DocPollMarkdown(r.Poll, opt)
84 | case "code":
85 | return DocCodeMarkdown(r.Code, opt)
86 | case "docsApp":
87 | return DocDocsAppMarkdown(r.DocsApp, opt)
88 | case "callout":
89 | return DocCalloutMarkdown(r.Callout, opt)
90 | case "undefinedBlock":
91 | return DocUndefinedBlockMarkdown(r.UndefinedBlock, opt)
92 | default:
93 | return fmt.Sprintf("", r.Type)
94 | }
95 | }
96 |
97 | func DocParagraphMarkdown(r *lark.DocParagraph, opt *FormatOpt) string {
98 | buf := new(strings.Builder)
99 |
100 | if r.Style != nil {
101 | if r.Style.HeadingLevel > 0 {
102 | buf.WriteString(strings.Repeat("#", int(r.Style.HeadingLevel)))
103 | buf.WriteString(" ")
104 | }
105 | if r.Style.List != nil {
106 | buf.WriteString(r.Style.List.ListTag())
107 | buf.WriteString(" ")
108 | }
109 | switch {
110 | case r.Style.Quote:
111 | buf.WriteString("> ")
112 | }
113 | }
114 |
115 | for _, v := range r.Elements {
116 | buf.WriteString(DocParagraphElementMarkdown(v, opt))
117 | }
118 |
119 | if r.Style != nil {
120 | if r.Style.List != nil && r.Style.List.IndentLevel > 0 {
121 | //
122 | } else {
123 | buf.WriteString("\n")
124 | }
125 | }
126 |
127 | return buf.String()
128 | }
129 |
130 | func DocGalleryMarkdown(r *lark.DocGallery, opt *FormatOpt) string {
131 | buf := new(strings.Builder)
132 |
133 | for _, v := range r.ImageList {
134 | buf.WriteString(DocImageItemMarkdown(v, opt))
135 | }
136 |
137 | return buf.String()
138 | }
139 |
140 | func DocImageItemMarkdown(r *lark.DocImageItem, opt *FormatOpt) string {
141 | if opt.LarkClient == nil {
142 | return fmt.Sprintf("`[image: %s]`", r.FileToken)
143 | }
144 |
145 | target := downloadFile(opt.ctx, r.FileToken, r.FileToken+".jpg", opt)
146 | return fmt.Sprintf("
", target, r.Width, r.Height)
147 | }
148 |
149 | func DocChatGroupMarkdown(r *lark.DocChatGroup, opt *FormatOpt) string {
150 | return fmt.Sprintf("`[chat: %s]`", r.OpenChatID)
151 | }
152 |
153 | func DocTableMarkdown(r *lark.DocTable, opt *FormatOpt) string {
154 | // todo
155 | buf := new(strings.Builder)
156 |
157 | return buf.String()
158 | }
159 |
160 | func DocHorizontalLineMarkdown(r *lark.DocHorizontalLine, opt *FormatOpt) string {
161 | return "\n---\n"
162 | }
163 |
164 | func DocEmbeddedPageMarkdown(r *lark.DocEmbeddedPage, opt *FormatOpt) string {
165 | return fmt.Sprintf("[embedded-page: %s](%s)", r.Type, r.Url)
166 | }
167 |
168 | func DocSheetMarkdown(r *lark.DocSheet, opt *FormatOpt) string {
169 | return fmt.Sprintf("`[sheet: %s]`", r.Token)
170 | }
171 |
172 | func DocBitableMarkdown(r *lark.DocBitable, opt *FormatOpt) string {
173 | return fmt.Sprintf("`[bitable: %s / %s]`", r.ViewType, r.Token)
174 | }
175 |
176 | func DocDiagramMarkdown(r *lark.DocDiagram, opt *FormatOpt) string {
177 | return fmt.Sprintf("`[diagram: %s / %s]`", r.DiagramType, r.Token)
178 | }
179 |
180 | func DocPollMarkdown(r *lark.DocPoll, opt *FormatOpt) string {
181 | return fmt.Sprintf("`[poll: %s]`", r.Token)
182 | }
183 |
184 | func DocCodeMarkdown(r *lark.DocCode, opt *FormatOpt) string {
185 | buf := new(strings.Builder)
186 |
187 | buf.WriteString("```")
188 | if r.Language != "" {
189 | buf.WriteString(r.Language)
190 | }
191 | buf.WriteString("\n")
192 |
193 | buf.WriteString(DocBodyMarkdown(r.Body, opt))
194 |
195 | buf.WriteString("\n")
196 | buf.WriteString("```")
197 |
198 | return buf.String()
199 | }
200 |
201 | func DocDocsAppMarkdown(r *lark.DocDocsApp, opt *FormatOpt) string {
202 | return fmt.Sprintf("`[docs-app: %s]`", r.TypeID)
203 | }
204 |
205 | func DocCalloutMarkdown(r *lark.DocCallout, opt *FormatOpt) string {
206 | buf := new(strings.Builder)
207 |
208 | buf.WriteString("```")
209 | buf.WriteString("\n")
210 |
211 | buf.WriteString(DocBodyMarkdown(r.Body, opt))
212 |
213 | buf.WriteString("\n")
214 | buf.WriteString("```")
215 |
216 | return buf.String()
217 | }
218 |
219 | func DocUndefinedBlockMarkdown(r *lark.DocUndefinedBlock, opt *FormatOpt) string {
220 | return "`[undefined-block]`"
221 | }
222 |
223 | func DocParagraphElementMarkdown(r *lark.DocParagraphElement, opt *FormatOpt) string {
224 | switch r.Type {
225 | case "textRun":
226 | return DocTextRunMarkdown(r.TextRun, opt)
227 | case "docsLink":
228 | return DocDocsLinkMarkdown(r.DocsLink, opt)
229 | case "person":
230 | return DocPersonMarkdown(r.Person, opt)
231 | case "equation":
232 | return DocEquationMarkdown(r.Equation, opt)
233 | case "reminder":
234 | return DocReminderMarkdown(r.Reminder, opt)
235 | case "file":
236 | return DocFileMarkdown(r.File, opt)
237 | case "jira":
238 | return DocJiraMarkdown(r.Jira, opt)
239 | case "undefinedElement":
240 | return DocUndefinedElementMarkdown(r.UndefinedElement, opt)
241 | default:
242 | return fmt.Sprintf("", r.Type)
243 | }
244 | }
245 |
246 | func DocTextRunMarkdown(r *lark.DocTextRun, opt *FormatOpt) string {
247 | // **加粗**
248 | // _斜体_
249 | // ~~删除线~~
250 | // 下划线
251 | // `行内代码`
252 | // [title](url)
253 | buf := new(strings.Builder)
254 | if r.Style != nil {
255 | switch {
256 | case r.Style.Bold:
257 | buf.WriteString("**")
258 | case r.Style.Italic:
259 | buf.WriteString("_")
260 | case r.Style.StrikeThrough:
261 | buf.WriteString("~~")
262 | case r.Style.Underline:
263 | buf.WriteString("")
264 | case r.Style.CodeInline:
265 | buf.WriteString("`")
266 | case r.Style.Link != nil && r.Style.Link.URL != "":
267 | buf.WriteString("[")
268 | }
269 | }
270 |
271 | buf.WriteString(r.Text)
272 |
273 | if r.Style != nil {
274 | switch {
275 | case r.Style.Bold:
276 | buf.WriteString("**")
277 | case r.Style.Italic:
278 | buf.WriteString("_")
279 | case r.Style.StrikeThrough:
280 | buf.WriteString("~~")
281 | case r.Style.Underline:
282 | buf.WriteString("")
283 | case r.Style.CodeInline:
284 | buf.WriteString("`")
285 | case r.Style.Link != nil && r.Style.Link.URL != "":
286 | buf.WriteString("](")
287 | buf.WriteString(r.Style.Link.URL)
288 | buf.WriteString(")")
289 | }
290 | }
291 |
292 | return buf.String()
293 | }
294 |
295 | func DocDocsLinkMarkdown(r *lark.DocDocsLink, opt *FormatOpt) string {
296 | return fmt.Sprintf("[%s](%s)", "云文档", r.URL)
297 | }
298 |
299 | func DocPersonMarkdown(r *lark.DocPerson, opt *FormatOpt) string {
300 | return "@" + r.OpenID
301 | }
302 |
303 | func DocEquationMarkdown(r *lark.DocEquation, opt *FormatOpt) string {
304 | return fmt.Sprintf("$$%s$$", r.Equation)
305 | }
306 |
307 | func DocReminderMarkdown(r *lark.DocReminder, opt *FormatOpt) string {
308 | return "`[doc-reminder]`"
309 | }
310 |
311 | func DocFileMarkdown(r *lark.DocFile, opt *FormatOpt) string {
312 | if opt.LarkClient == nil {
313 | return fmt.Sprintf("`[file: %s / %s]`", r.FileName, r.FileToken)
314 | }
315 |
316 | target := downloadFile(opt.ctx, r.FileToken, r.FileName, opt)
317 | return fmt.Sprintf("[file: %s](%s)", r.FileName, target)
318 | }
319 |
320 | func DocJiraMarkdown(r *lark.DocJira, opt *FormatOpt) string {
321 | return fmt.Sprintf("`[jira: %s / %s]`", r.JiraType, r.Token)
322 | }
323 |
324 | func DocUndefinedElementMarkdown(r *lark.DocUndefinedElement, opt *FormatOpt) string {
325 | return "`[undefined-element]`"
326 | }
327 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/testdata/2/data.md:
--------------------------------------------------------------------------------
1 | # Lark SDK Ext 使用指南
2 |
3 | > Lark SDK 项目:https://github.com/chyroc/lark
4 | > Lark SDK Ext 是在 Lark SDK 上层,面向 Drive/Sheet/Doc 等操作封装的一层方法
5 | > 注意:下面所有的 ctx 都是指在一次请求过程的上下文,是标准库 `context.Context` 的实例
6 |
7 | # 一些例子
8 |
9 | - 将图片马赛克化,并填充到 Sheet:https://github.com/chyroc/draw-lark-sheet
10 | # 初始化 Lark 客户端
11 |
12 | ```Go
13 | package main
14 |
15 | import (
16 | "github.com/chyroc/lark"
17 | )
18 |
19 | func main() {
20 | larkClient := lark.New(
21 | lark.WithAppCredential(r.AppID, r.AppSecret)
22 | )
23 | }
24 |
25 | ```
26 | > 注意:下面所有的 `larkCli` 都是指的 Lark SDK 客户端
27 | # Folder / 文件夹
28 |
29 | ## 创建我的空间跟目录 Folder Client
30 |
31 | ```Go
32 | package main
33 |
34 | import (
35 | "context"
36 |
37 | "github.com/chyroc/lark"
38 | "github.com/chyroc/lark/larkext"
39 | )
40 |
41 | func example(ctx context.Context, larkClient *lark.Lark) {
42 | folderRootClient, err := larkext.NewRootFolder(ctx, r)
43 | if err != nil {
44 | panic(err)
45 | }
46 |
47 | _ = folderRootClient
48 | }
49 |
50 | ```
51 | ## 从已有的 Folder Token 创建 Folder Client
52 |
53 | ```Go
54 | package main
55 |
56 | import (
57 | "context"
58 |
59 | "github.com/chyroc/lark"
60 | "github.com/chyroc/lark/larkext"
61 | )
62 |
63 | func example(ctx context.Context, larkClient *lark.Lark, folderToken string) {
64 | folderClient := larkext.NewFolder(larkClient, folderToken)
65 | }
66 |
67 | ```
68 | > 注意:下面提到的 `folderClient` 都是指这样创建的 Folder Client
69 |
70 | ## 获取文件夹的元信息
71 |
72 | ```Go
73 | package main
74 |
75 | import (
76 | "context"
77 |
78 | "github.com/chyroc/lark/larkext"
79 | )
80 |
81 | func example(ctx context.Context, folderClient *larkext.Folder) {
82 | meta, err := folderClient.Meta(ctx)
83 | if err != nil {
84 | panic(err)
85 | }
86 |
87 | _ = meta
88 | }
89 |
90 | ```
91 | ## 列出一个文件下的文件列表
92 |
93 | ```Go
94 | package main
95 |
96 | import (
97 | "context"
98 |
99 | "github.com/chyroc/lark/larkext"
100 | )
101 |
102 | func example(ctx context.Context, folderClient *larkext.Folder) {
103 | files, err := folderClient.ListFiles(ctx)
104 | if err != nil {
105 | panic(err)
106 | }
107 |
108 | _ = files
109 | }
110 |
111 | ```
112 | ## 在文件夹内创建文件夹
113 |
114 | ```Go
115 | package main
116 |
117 | import (
118 | "context"
119 |
120 | "github.com/chyroc/lark/larkext"
121 | )
122 |
123 | func example(ctx context.Context, folderClient *larkext.Folder) {
124 | childFolderClient, err := folderClient.NewFolder(ctx, "child")
125 | if err != nil {
126 | panic(err)
127 | }
128 |
129 | _ = childFolderClient
130 | }
131 |
132 | ```
133 | ## 在文件夹内创建文档 Doc
134 |
135 | ```Go
136 | package main
137 |
138 | import (
139 | "context"
140 |
141 | "github.com/chyroc/lark/larkext"
142 | )
143 |
144 | func example(ctx context.Context, folderClient *larkext.Folder) {
145 | docClient, err := folderClient.NewDoc(ctx, "doc title")
146 | if err != nil {
147 | panic(err)
148 | }
149 |
150 | _ = docClient
151 | }
152 |
153 | ```
154 | ## 在文件夹内创建表格 Sheet
155 |
156 | ```Go
157 | package main
158 |
159 | import (
160 | "context"
161 |
162 | "github.com/chyroc/lark/larkext"
163 | )
164 |
165 | func example(ctx context.Context, folderClient *larkext.Folder) {
166 | sheetClient, err := folderClient.NewSheet(ctx, "sheet title")
167 | if err != nil {
168 | panic(err)
169 | }
170 |
171 | _ = sheetClient
172 | }
173 |
174 | ```
175 | ## 删除文档
176 |
177 | ```Go
178 | package main
179 |
180 | import (
181 | "context"
182 |
183 | "github.com/chyroc/lark/larkext"
184 | )
185 |
186 | func example(ctx context.Context, folderClient *larkext.Folder) {
187 | err := folderClient.DeleteDoc(ctx, "doc-token")
188 | if err != nil {
189 | panic(err)
190 | }
191 | }
192 |
193 | ```
194 | ## 删除表格
195 |
196 | ```Go
197 | package main
198 |
199 | import (
200 | "context"
201 |
202 | "github.com/chyroc/lark/larkext"
203 | )
204 |
205 | func example(ctx context.Context, folderClient *larkext.Folder) {
206 | err := folderClient.DeleteSheet(ctx, "sheet-token")
207 | if err != nil {
208 | panic(err)
209 | }
210 | }
211 |
212 | ```
213 | # Sheet / 电子表格
214 |
215 | ## Sheet 使用前说明
216 |
217 | ### 表格坐标、索引
218 |
219 | 表格以左上角第一个单元格作为原点,坐标是:`(1, 1)`,体现为 Sheet 坐标就是:`A1`。
220 | 横向是 X 轴,从左往右增加;纵向是 Y 轴,从上往下增加。
221 |
222 | ### 将横坐标 X 轴,从数字转成 `A` `Z` `AZ` 等格式
223 |
224 | ```Go
225 | package main
226 |
227 | import (
228 | "github.com/chyroc/lark/larkext"
229 | )
230 |
231 | func exampled() {
232 | larkext.ItoCol(1) _// A_
233 | _ _larkext.ItoCol(26) _// Z_
234 | _ _larkext.ItoCol(27) _// AA_
235 | }
236 |
237 | ```
238 | 将单元格范围 `(x1, y1) , (x2, y2)` 转成 `sheet!A1:D3` 格式
239 | ```Go
240 | package main
241 |
242 | import (
243 | "github.com/chyroc/lark/larkext"
244 | )
245 |
246 | func exampled() {
247 | larkext.CellRange("sheet1", 1, 1, 2, 2) _// sheet1!A1:B2_
248 | _ _larkext.CellRange("sheet1", 1, 100, 26, 200) _// sheet1!A100:Z200_
249 | }
250 |
251 | ```
252 | ## 从已有的 Sheet 创建 Sheet 客户端
253 |
254 | ```Go
255 | package main
256 |
257 | import (
258 | "context"
259 |
260 | "github.com/chyroc/lark"
261 | "github.com/chyroc/lark/larkext"
262 | )
263 |
264 | func example(ctx context.Context, larkClient *lark.Lark, sheetToken string) {
265 | sheetClient := larkext.NewSheet(larkClient, sheetToken)
266 |
267 | _ = sheetClient
268 | }
269 |
270 | ```
271 | > 注意:下面所有的 `sheetClient` 都是指 larkext.Sheet 实例
272 |
273 | ## 创建新的 Sheet,并创建它的客户端
274 |
275 | ```Go
276 | package main
277 |
278 | import (
279 | "context"
280 |
281 | "github.com/chyroc/lark/larkext"
282 | )
283 |
284 | func example(ctx context.Context, folderClient *larkext.Folder) {
285 | sheetClient, err := folderClient.NewSheet(ctx, "sheet title")
286 | if err != nil {
287 | panic(err)
288 | }
289 |
290 | _ = sheetClient
291 | }
292 |
293 | ```
294 |
295 | ## 获取 Sheet 元数据
296 |
297 | ```Go
298 | package main
299 |
300 | import (
301 | "context"
302 |
303 | "github.com/chyroc/lark/larkext"
304 | "github.com/davecgh/go-spew/spew"
305 | )
306 |
307 | func example(ctx context.Context, sheetIns *larkext.Sheet) {
308 | meta, err := sheetIns.Meta(ctx)
309 | if err != nil {
310 | panic(err)
311 | }
312 | spew.Dump(meta)
313 | }
314 |
315 | ```
316 | ## 获取 Sheet 数据
317 |
318 | ```Go
319 | package main
320 |
321 | import (
322 | "context"
323 | "fmt"
324 |
325 | "github.com/chyroc/lark"
326 | "github.com/chyroc/lark/larkext"
327 | )
328 |
329 | func example(ctx context.Context, sheetIns *larkext.Sheet) {
330 | cellRange := larkext.CellRange("sheet-id", 1, 1, 10, 10)
331 | resp, err := sheetIns.Get(ctx, cellRange, &lark.GetSheetValueReq{})
332 | if err != nil {
333 | panic(err)
334 | }
335 | for _, vv := range resp.ValueRange.Values {
336 | for _, v := range vv {
337 | switch v.Type() {
338 | case lark.SheetContentTypeString:
339 | fmt.Println(*v.String)
340 | case lark.SheetContentTypeInt:
341 | fmt.Println(*v.Int)
342 | }
343 | }
344 | }
345 | }
346 |
347 | ```
348 | ## 删除 Sheet 自己
349 |
350 | ```Go
351 | package main
352 |
353 | import (
354 | "context"
355 |
356 | "github.com/chyroc/lark/larkext"
357 | )
358 |
359 | func example(ctx context.Context, sheetIns *larkext.Sheet) {
360 | err := sheetIns.Delete(ctx)
361 | if err != nil {
362 | panic(err)
363 | }
364 | }
365 |
366 | ```
367 |
368 |
369 | ## 设置 Sheet 标题
370 |
371 | ```Go
372 | package test
373 |
374 | import (
375 | "context"
376 |
377 | "github.com/chyroc/lark/larkext"
378 | )
379 |
380 | func example(ctx context.Context, sheetIns *larkext.Sheet) {
381 | sheetIns.SetTitle(ctx, "this is title")
382 | }
383 |
384 | ```
385 |
386 | ## 设置工作表标题
387 |
388 | ```Go
389 | package main
390 |
391 | import (
392 | "context"
393 |
394 | "github.com/chyroc/lark/larkext"
395 | )
396 |
397 | func example(ctx context.Context, sheetClient *larkext.Sheet) {
398 | err := sheetClient.SetSheetTitle(ctx, "sheet-id", "sheet title")
399 | if err != nil {
400 | panic(err)
401 | }
402 | }
403 |
404 | ```
405 |
406 | ## 设置工作表位置
407 |
408 | ```Go
409 | package main
410 |
411 | import (
412 | "context"
413 |
414 | "github.com/chyroc/lark/larkext"
415 | )
416 |
417 | func example(ctx context.Context, sheetClient *larkext.Sheet) {
418 | err := sheetClient.SetSheetIndex(ctx, "sheet-id", 1)
419 | if err != nil {
420 | panic(err)
421 | }
422 | }
423 |
424 | ```
425 | ## 隐藏工作表
426 |
427 | ```Go
428 | package main
429 |
430 | import (
431 | "context"
432 |
433 | "github.com/chyroc/lark/larkext"
434 | )
435 |
436 | func example(ctx context.Context, sheetClient *larkext.Sheet) {
437 | err := sheetClient.HideSheet(ctx, "sheet-id", true)
438 | if err != nil {
439 | panic(err)
440 | }
441 | }
442 |
443 | ```
444 |
445 | ## 冻结行与列
446 |
447 | ```Go
448 | package main
449 |
450 | import (
451 | "context"
452 |
453 | "github.com/chyroc/lark/larkext"
454 | )
455 |
456 | func example(ctx context.Context, sheetClient *larkext.Sheet) {
457 | _// 冻结 1-2 行,1-3(A-C) 列_
458 | _ _{
459 | err := sheetClient.FrozenSheet(ctx, "sheet-id", 2, 3)
460 | if err != nil {
461 | panic(err)
462 | }
463 | }
464 |
465 | _// 取消冻结_
466 | _ _{
467 | err := sheetClient.FrozenSheet(ctx, "sheet-id", 0,0)
468 | if err != nil {
469 | panic(err)
470 | }
471 | }
472 | }
473 |
474 | ```
475 | ## 锁定工作表
476 |
477 | ```Go
478 | package main
479 |
480 | import (
481 | "context"
482 |
483 | "github.com/chyroc/lark/larkext"
484 | )
485 |
486 | func example(ctx context.Context, sheetClient *larkext.Sheet) {
487 | err := sheetClient.LockSheet(ctx, "sheet-id", "lock-info", nil)
488 | if err != nil {
489 | panic(err)
490 | }
491 | }
492 |
493 | ```
494 |
495 | ## 解锁工作表
496 |
497 | ```Go
498 | package main
499 |
500 | import (
501 | "context"
502 |
503 | "github.com/chyroc/lark/larkext"
504 | )
505 |
506 | func example(ctx context.Context, sheetClient *larkext.Sheet) {
507 | err := sheetClient.UnlockSheet(ctx, "sheet-id")
508 | if err != nil {
509 | panic(err)
510 | }
511 | }
512 |
513 | ```
514 | ## 移动行数据
515 |
516 | ```Go
517 | package main
518 |
519 | import (
520 | "context"
521 |
522 | "github.com/chyroc/lark"
523 | "github.com/chyroc/lark/larkext"
524 | )
525 |
526 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
527 | _ = sheetClient.MoveRows(ctx, sheetID, 3, 2, -1)
528 | }
529 |
530 | ```
531 | > 将第 3 行开始,连续 2 行的数据,向上(负号表示上)移动 1 行
532 | > 上面的数据会被积压下来
533 |
534 |
535 | ## 移动列数据
536 |
537 | ```Go
538 | package main
539 |
540 | import (
541 | "context"
542 |
543 | "github.com/chyroc/lark"
544 | "github.com/chyroc/lark/larkext"
545 | )
546 |
547 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
548 | _ = sheetClient.MoveCols(ctx, sheetID, 3, 2, -2)
549 | }
550 |
551 | ```
552 | > 将第 3 列开始,连续 2 列的数据,向左(负号 表示左)移动 2 列
553 | > 左边的数据会被挤压到右边
554 |
555 | ## 插入行数据
556 |
557 | ```Go
558 | package main
559 |
560 | import (
561 | "context"
562 |
563 | "github.com/chyroc/lark"
564 | "github.com/chyroc/lark/larkext"
565 | )
566 |
567 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
568 | _ = sheetClient.InsertRows(ctx, sheetID, 3, 2)
569 | }
570 |
571 | ```
572 | > 从第 3 行开始,插入连续 2 行的空数据
573 | > 原本第3、4行的数据会被挤压到下边
574 |
575 |
576 | ## 插入列数据
577 |
578 | ```Go
579 | package main
580 |
581 | import (
582 | "context"
583 |
584 | "github.com/chyroc/lark"
585 | "github.com/chyroc/lark/larkext"
586 | )
587 |
588 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
589 | _ = sheetClient.InsertCols(ctx, sheetID, 3, 2)
590 | }
591 |
592 | ```
593 | > 从第 3 列开始,插入连续 2 列的空数据
594 | > 原本第3、4列的数据会被挤压到右边
595 |
596 | ## 增加行
597 |
598 | ```Go
599 | package main
600 |
601 | import (
602 | "context"
603 |
604 | "github.com/chyroc/lark"
605 | "github.com/chyroc/lark/larkext"
606 | )
607 |
608 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
609 | err := sheetClient.AddRows(ctx, sheetID, 2)
610 |
611 | _ = err
612 | }
613 |
614 | ```
615 | > 给只有 5 行的工作表,增加 2 行
616 | 
617 | ## 增加列
618 |
619 | ```Go
620 | package main
621 |
622 | import (
623 | "context"
624 |
625 | "github.com/chyroc/lark"
626 | "github.com/chyroc/lark/larkext"
627 | )
628 |
629 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
630 | err := sheetClient.AddCols(ctx, sheetID, 2)
631 |
632 | _ = err
633 | }
634 |
635 | ```
636 | > 给只有 A B 两列的工作表,增加 2 列
637 | 
638 | ## 追加数据
639 |
640 | ```Go
641 | package main
642 |
643 | import (
644 | "context"
645 |
646 | "github.com/chyroc/go-ptr"
647 | "github.com/chyroc/lark"
648 | "github.com/chyroc/lark/larkext"
649 | )
650 |
651 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
652 | err := sheetClient.Append(ctx, sheetID"!A:C", [][]lark.SheetContent{
653 | {
654 | {String: ptr.String("string value")},
655 | {Link: &lark.SheetValueLink{Text: "Google", Link: "https://google.com/"}},
656 | },
657 | {
658 | {Formula: &lark.SheetValueFormula{Text: "=A1"}},
659 | {AtDoc: &lark.SheetValueAtDoc{ObjType: "sheet", Text: "shtcnkAi6Xr5Nl6I0LAaGxWjRzd"}},
660 | },
661 | }, nil)
662 | if err != nil {
663 | panic(err)
664 | }
665 | }
666 |
667 | ```
668 | > 默认情况下,从第二行开始的非空数据会被覆盖
669 | 
670 | > 可以指定追加数据模式为 `INSERT_ROWS`
671 | 
672 | ## 设置行的可见性
673 |
674 | ```Go
675 | package main
676 |
677 | import (
678 | "context"
679 |
680 | "github.com/chyroc/lark"
681 | "github.com/chyroc/lark/larkext"
682 | )
683 |
684 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
685 | err := sheetClient.SetRowsVisible(ctx, sheetID, 2, 2, false)
686 |
687 | _ = err
688 | }
689 |
690 | ```
691 | > 将第 2 行开始的连续的 2 行,设置为 不可见
692 | 
693 | ## 设置列的可见性
694 |
695 | ```Go
696 | package main
697 |
698 | import (
699 | "context"
700 |
701 | "github.com/chyroc/lark"
702 | "github.com/chyroc/lark/larkext"
703 | )
704 |
705 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
706 | err := sheetClient.SetColsVisible(ctx, sheetID, 2, 2, false)
707 |
708 | _ = err
709 | }
710 |
711 | ```
712 | > 将第 2 列开始的连续的 2 列,设置为 不可见
713 | 
714 | ## 设置行的高度
715 |
716 | > 默认的行高是 27
717 | ```Go
718 | package main
719 |
720 | import (
721 | "context"
722 |
723 | "github.com/chyroc/lark"
724 | "github.com/chyroc/lark/larkext"
725 | )
726 |
727 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
728 | err := sheetClient.SetRowsSize(ctx, sheetID, 2, 2, 54)
729 |
730 | _ = err
731 | }
732 |
733 | ```
734 | > 将第 2 行开始的连续 2 行的行高,设置为 54
735 | 
736 | ## 设置列的宽度
737 |
738 | > 默认的列宽是 105
739 | ```Go
740 | package main
741 |
742 | import (
743 | "context"
744 |
745 | "github.com/chyroc/lark"
746 | "github.com/chyroc/lark/larkext"
747 | )
748 |
749 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
750 | err := sheetClient.SetRowsSize(ctx, sheetID, 2, 2, 50)
751 |
752 | _ = err
753 | }
754 |
755 | ```
756 | > 将第 2 列开始的连续 2 列的列宽,设置为 50
757 | 
758 | ## 删除行
759 |
760 | ```Go
761 | package main
762 |
763 | import (
764 | "context"
765 |
766 | "github.com/chyroc/lark"
767 | "github.com/chyroc/lark/larkext"
768 | )
769 |
770 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
771 | err := sheetClient.DeleteRows(ctx, sheetID, 2, 2)
772 |
773 | _ = err
774 | }
775 |
776 | ```
777 | > 删除第 2 行开始的连续 2 行
778 | 
779 | ## 删除列
780 |
781 | ```Go
782 | package main
783 |
784 | import (
785 | "context"
786 |
787 | "github.com/chyroc/lark"
788 | "github.com/chyroc/lark/larkext"
789 | )
790 |
791 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
792 | err := sheetClient.DeleteCols(ctx, sheetID, 2, 2)
793 |
794 | _ = err
795 | }
796 |
797 | ```
798 | > 删除第 2 列开始的连续 2 列
799 | 
800 | ## 设置单元格样式
801 |
802 | ```Go
803 | package main
804 |
805 | import (
806 | "context"
807 |
808 | "github.com/chyroc/go-ptr"
809 | "github.com/chyroc/lark"
810 | "github.com/chyroc/lark/larkext"
811 | )
812 |
813 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
814 | err := sheetClient.SetCellStyle(ctx, sheetID+"!A1:C3", &lark.SetSheetStyleReqAppendStyleStyle{
815 | Font: &lark.SetSheetStyleReqAppendStyleStyleFont{
816 | Bold: ptr.Bool(true),
817 | Italic: ptr.Bool(true),
818 | FontSize: ptr.String("10pt/1.5"),
819 | },
820 | TextDecoration: ptr.Int64(3),
821 | HAlign: ptr.Int64(1),
822 | VAlign: ptr.Int64(1),
823 | ForeColor: ptr.String("#000000"),
824 | BackColor: ptr.String("#21d11f"),
825 | })
826 |
827 | _ = err
828 | }
829 |
830 | ```
831 | > 设置 A1 到 C3 区域内,加粗,删除线,切下划线,背景色
832 | 
833 | ## 清除单元格样式
834 |
835 | ```Go
836 | package main
837 |
838 | import (
839 | "context"
840 |
841 | "github.com/chyroc/lark/larkext"
842 | )
843 |
844 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
845 | err := sheetClient.CleanCellStyle(ctx, larkext.CellRange(sheetID, 1, 1, 3, 3))
846 |
847 | _ = err
848 | }
849 |
850 | ```
851 | > 清除单元格上所有的样式
852 | 
853 | ## 合并单元格
854 |
855 | ```Go
856 | package main
857 |
858 | import (
859 | "context"
860 |
861 | "github.com/chyroc/lark"
862 | "github.com/chyroc/lark/larkext"
863 | )
864 |
865 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
866 | err := sheetClient.MergeCell(ctx, sheetID+"!A1:C3", "MERGE_ALL")
867 |
868 | _ = err
869 | }
870 |
871 | ```
872 | > mergeType 选择 MERGE_ALL,将 A1 到 C3 合并为一个单元格
873 | 
874 | > mergeType 选择 MERGE_ROWS,将 A1 到 C3 按行合并为一个单元格
875 | 
876 | > mergeType 选择 MERGE_COLUMNS,将 A1 到 C3 按行合并为一个单元格
877 | 
878 | ## 取消合并单元格
879 |
880 | ```Go
881 | package main
882 |
883 | import (
884 | "context"
885 |
886 | "github.com/chyroc/lark"
887 | "github.com/chyroc/lark/larkext"
888 | )
889 |
890 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
891 | err := sheetClient.UnmergeCell(ctx, sheetID+"!A1:C3")
892 |
893 | _ = err
894 | }
895 |
896 | ```
897 | > 将范围 A2:C2 范围内的合并单元格取消合并
898 | 
899 | ## 单元格写入内容
900 |
901 | ```Go
902 | package main
903 |
904 | import (
905 | "context"
906 |
907 | "github.com/chyroc/go-ptr"
908 | "github.com/chyroc/lark"
909 | "github.com/chyroc/lark/larkext"
910 | "github.com/davecgh/go-spew/spew"
911 | )
912 |
913 | func exampled(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
914 | err := sheetClient.SetSheetValue(ctx, larkext.CellRange(sheetID, 1, 1, 3, 2), [][]lark.SheetContent{
915 | {
916 | {String: ptr.String("(1,1) 字符串")},
917 | {Int: ptr.Int64(100)},
918 | {Link: &lark.SheetValueLink{Text: "Google", Link: "https://google.com"}},
919 | },
920 | {
921 | {Formula: &lark.SheetValueFormula{Text: "=A1"}},
922 | {AtDoc: &lark.SheetValueAtDoc{ObjType: "sheet", Text: sheetClient.SheetToken()}},
923 | },
924 | })
925 | _ = err
926 | }
927 |
928 | ```
929 | > 向一个 3-2 范围的单元格写入内容,包含字符串,数字,链接,公式,文档等
930 |
931 | ## 单元格写入图片
932 |
933 | ```Go
934 | package main
935 |
936 | import (
937 | "context"
938 | "io/ioutil"
939 |
940 | "github.com/chyroc/lark/larkext"
941 | )
942 |
943 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID, filepath string) {
944 | images, err := ioutil.ReadFile(filepath)
945 | if err != nil {
946 | panic(err)
947 | }
948 |
949 | _ = sheetClient.SetSheetValueImage(ctx, larkext.CellRange(sheetID, 2, 2, 2, 2), images)
950 | _ = sheetClient.SetColsSize(ctx, sheetID, 2, 1, 100)
951 | _ = sheetClient.SetRowsSize(ctx, sheetID, 2, 1, 100)
952 | }
953 |
954 | ```
955 | > 在 B2 位置写入一张图片,并将这个单元格的高和宽都设置为 100
956 | 
957 | ## 批量写入单元格内容
958 |
959 | > 批量写入主要适用于单元格不连续的情况
960 | ```Go
961 | package main
962 |
963 | import (
964 | "context"
965 |
966 | "github.com/chyroc/go-ptr"
967 | "github.com/chyroc/lark"
968 | "github.com/chyroc/lark/larkext"
969 | "github.com/davecgh/go-spew/spew"
970 | )
971 |
972 | func exampled(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
973 | err := sheetClient.BatchSetSheetValue(ctx, []*lark.BatchSetSheetValueReqValueRange{
974 | {
975 | Range: larkext.CellRange(sheetID, 1, 1, 1, 1),
976 | Values: [][]lark.SheetContent{
977 | {
978 | {String: ptr.String("(1,1) 字符串")},
979 | },
980 | },
981 | },
982 | {
983 | Range: larkext.CellRange(sheetID, 2, 2, 2, 2),
984 | Values: [][]lark.SheetContent{
985 | {
986 | {Link: &lark.SheetValueLink{Text: "Google", Link: "https://google.com"}},
987 | },
988 | },
989 | },
990 | {
991 | Range: larkext.CellRange(sheetID, 3, 3, 3, 3),
992 | Values: [][]lark.SheetContent{
993 | {
994 | {AtDoc: &lark.SheetValueAtDoc{ObjType: "sheet", Text: sheetClient.SheetToken()}},
995 | },
996 | },
997 | },
998 | })
999 | _ = err
1000 | }
1001 |
1002 | ```
1003 | > 向单元格的 `(1, 1)`,`(2, 2)`,`(3, 3` 分别写入字符串,链接和文档内容
1004 |
1005 | ## 搜索表格
1006 |
1007 | ```Go
1008 | package main
1009 |
1010 | import (
1011 | "context"
1012 | "fmt"
1013 |
1014 | "github.com/chyroc/lark"
1015 | "github.com/chyroc/lark/larkext"
1016 | )
1017 |
1018 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
1019 | res, err := sheetClient.SearchSheet(ctx, sheetID, "6", nil)
1020 | if err != nil {
1021 | panic(err)
1022 | }
1023 | fmt.Println("march cells:", res.MatchedCells)
1024 | fmt.Println("march formula cells:", res.MatchedFormulaCells)
1025 | }
1026 |
1027 | ```
1028 | > 前三列是数字,第四列是前三列的和,搜索:6,可以搜索出原始单元格 B2,和公式单元格 D1
1029 | 
1030 | ## 替换表格
1031 |
1032 | ```Go
1033 | package main
1034 |
1035 | import (
1036 | "context"
1037 | "fmt"
1038 |
1039 | "github.com/chyroc/lark"
1040 | "github.com/chyroc/lark/larkext"
1041 | )
1042 |
1043 | func example(ctx context.Context, sheetClient *larkext.Sheet, sheetID string) {
1044 | _, err := sheetClient.Replace(ctx, sheetID, "6", "replace-6", nil)
1045 | if err != nil {
1046 | panic(err)
1047 | }
1048 | }
1049 |
1050 | ```
1051 | > 前三列是数字,第四列是前三列的和,将 6 替换为 replace-6
1052 | 
1053 |
1054 | # Doc / 文档
1055 |
1056 | ## 从已有的 Doc 创建 Doc 客户端
1057 |
1058 | ```Go
1059 | package main
1060 |
1061 | import (
1062 | "context"
1063 |
1064 | "github.com/chyroc/lark"
1065 | "github.com/chyroc/lark/larkext"
1066 | )
1067 |
1068 | func example(larkClient *lark.Lark, docToken string) {
1069 | docClient := larkext.NewDoc(larkClient, docToken)
1070 |
1071 | _ = docClient
1072 | }
1073 |
1074 | ```
1075 | ## 获取文档元信息
1076 |
1077 | ```Go
1078 | package main
1079 |
1080 | import (
1081 | "context"
1082 |
1083 | "github.com/chyroc/lark"
1084 | "github.com/chyroc/lark/larkext"
1085 | )
1086 |
1087 | func example(ctx context.Context, docClient *larkext.Doc) {
1088 | meta, err := docClient.Meta(ctx)
1089 | if err != nil {
1090 | panic(err)
1091 | }
1092 |
1093 | _ = meta
1094 | }
1095 |
1096 | ```
1097 |
1098 | ## 获取文档文本内容
1099 |
1100 | ```Go
1101 | package main
1102 |
1103 | import (
1104 | "context"
1105 | "fmt"
1106 |
1107 | "github.com/chyroc/lark"
1108 | "github.com/chyroc/lark/larkext"
1109 | )
1110 |
1111 | func example(ctx context.Context, docClient *larkext.Doc) {
1112 | text, err := docClient.RawContent(ctx)
1113 | if err != nil {
1114 | panic(err)
1115 | }
1116 |
1117 | fmt.Println(text)
1118 | }
1119 |
1120 | ```
1121 | > 获取一个标题为 test 的文档的文本内容
1122 | 
1123 | ## 获取文档的富文本内容
1124 |
1125 | ```Go
1126 | package main
1127 |
1128 | import (
1129 | "context"
1130 | "fmt"
1131 |
1132 | "github.com/chyroc/lark"
1133 | "github.com/chyroc/lark/larkext"
1134 | "github.com/davecgh/go-spew/spew"
1135 | )
1136 |
1137 | func example(ctx context.Context, docClient *larkext.Doc) {
1138 | content, err := docClient.Content(ctx)
1139 | if err != nil {
1140 | panic(err)
1141 | }
1142 |
1143 | spew.Dump(content)
1144 | }
1145 |
1146 | ```
1147 | > 获取一个标题为 test 的文档的富文本内容
1148 | 
1149 |
1150 |
1151 |
1152 |
--------------------------------------------------------------------------------
/testdata/1/data.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": {
3 | "elements": [
4 | {
5 | "type": "textRun",
6 | "textRun": {
7 | "text": "📔 这是一个飞书文档的例子",
8 | "style": {},
9 | "location": {
10 | "zoneId": "0",
11 | "startIndex": 0,
12 | "endIndex": 14
13 | }
14 | }
15 | }
16 | ],
17 | "location": {
18 | "zoneId": "0",
19 | "startIndex": 0,
20 | "endIndex": 14
21 | },
22 | "lineId": "w5mwCd"
23 | },
24 | "body": {
25 | "blocks": [
26 | {
27 | "type": "paragraph",
28 | "paragraph": {
29 | "elements": [
30 | {
31 | "type": "textRun",
32 | "textRun": {
33 | "text": "这是一个飞书文档的例子,包含所有 Markdown 支持的语法",
34 | "style": {},
35 | "location": {
36 | "zoneId": "0",
37 | "startIndex": 16,
38 | "endIndex": 47
39 | }
40 | }
41 | }
42 | ],
43 | "style": {
44 | "quote": true
45 | },
46 | "location": {
47 | "zoneId": "0",
48 | "startIndex": 15,
49 | "endIndex": 47
50 | },
51 | "lineId": "5YgXsL"
52 | }
53 | },
54 | {
55 | "type": "paragraph",
56 | "paragraph": {
57 | "elements": [],
58 | "style": {},
59 | "location": {
60 | "zoneId": "0",
61 | "startIndex": 48,
62 | "endIndex": 49
63 | },
64 | "lineId": "FWZTIo"
65 | }
66 | },
67 | {
68 | "type": "paragraph",
69 | "paragraph": {
70 | "elements": [
71 | {
72 | "type": "textRun",
73 | "textRun": {
74 | "text": "标题",
75 | "style": {},
76 | "location": {
77 | "zoneId": "0",
78 | "startIndex": 51,
79 | "endIndex": 53
80 | }
81 | }
82 | }
83 | ],
84 | "style": {
85 | "headingLevel": 1
86 | },
87 | "location": {
88 | "zoneId": "0",
89 | "startIndex": 50,
90 | "endIndex": 53
91 | },
92 | "lineId": "lrQpJ8"
93 | }
94 | },
95 | {
96 | "type": "paragraph",
97 | "paragraph": {
98 | "elements": [
99 | {
100 | "type": "textRun",
101 | "textRun": {
102 | "text": "二级标题",
103 | "style": {},
104 | "location": {
105 | "zoneId": "0",
106 | "startIndex": 55,
107 | "endIndex": 59
108 | }
109 | }
110 | }
111 | ],
112 | "style": {
113 | "headingLevel": 2
114 | },
115 | "location": {
116 | "zoneId": "0",
117 | "startIndex": 54,
118 | "endIndex": 59
119 | },
120 | "lineId": "oA8dUF"
121 | }
122 | },
123 | {
124 | "type": "paragraph",
125 | "paragraph": {
126 | "elements": [
127 | {
128 | "type": "textRun",
129 | "textRun": {
130 | "text": "三级标题",
131 | "style": {},
132 | "location": {
133 | "zoneId": "0",
134 | "startIndex": 61,
135 | "endIndex": 65
136 | }
137 | }
138 | }
139 | ],
140 | "style": {
141 | "headingLevel": 3
142 | },
143 | "location": {
144 | "zoneId": "0",
145 | "startIndex": 60,
146 | "endIndex": 65
147 | },
148 | "lineId": "DWclXO"
149 | }
150 | },
151 | {
152 | "type": "paragraph",
153 | "paragraph": {
154 | "elements": [
155 | {
156 | "type": "textRun",
157 | "textRun": {
158 | "text": "四级标题",
159 | "style": {},
160 | "location": {
161 | "zoneId": "0",
162 | "startIndex": 67,
163 | "endIndex": 71
164 | }
165 | }
166 | }
167 | ],
168 | "style": {
169 | "headingLevel": 4
170 | },
171 | "location": {
172 | "zoneId": "0",
173 | "startIndex": 66,
174 | "endIndex": 71
175 | },
176 | "lineId": "C7dxhe"
177 | }
178 | },
179 | {
180 | "type": "paragraph",
181 | "paragraph": {
182 | "elements": [
183 | {
184 | "type": "textRun",
185 | "textRun": {
186 | "text": "五级标题",
187 | "style": {},
188 | "location": {
189 | "zoneId": "0",
190 | "startIndex": 73,
191 | "endIndex": 77
192 | }
193 | }
194 | }
195 | ],
196 | "style": {
197 | "headingLevel": 5
198 | },
199 | "location": {
200 | "zoneId": "0",
201 | "startIndex": 72,
202 | "endIndex": 77
203 | },
204 | "lineId": "dro8Y0"
205 | }
206 | },
207 | {
208 | "type": "paragraph",
209 | "paragraph": {
210 | "elements": [
211 | {
212 | "type": "textRun",
213 | "textRun": {
214 | "text": "六级标题",
215 | "style": {},
216 | "location": {
217 | "zoneId": "0",
218 | "startIndex": 79,
219 | "endIndex": 83
220 | }
221 | }
222 | }
223 | ],
224 | "style": {
225 | "headingLevel": 6
226 | },
227 | "location": {
228 | "zoneId": "0",
229 | "startIndex": 78,
230 | "endIndex": 83
231 | },
232 | "lineId": "BhyDB7"
233 | }
234 | },
235 | {
236 | "type": "paragraph",
237 | "paragraph": {
238 | "elements": [
239 | {
240 | "type": "textRun",
241 | "textRun": {
242 | "text": "正文",
243 | "style": {},
244 | "location": {
245 | "zoneId": "0",
246 | "startIndex": 85,
247 | "endIndex": 87
248 | }
249 | }
250 | }
251 | ],
252 | "style": {
253 | "headingLevel": 1
254 | },
255 | "location": {
256 | "zoneId": "0",
257 | "startIndex": 84,
258 | "endIndex": 87
259 | },
260 | "lineId": "p0AQv5"
261 | }
262 | },
263 | {
264 | "type": "paragraph",
265 | "paragraph": {
266 | "elements": [
267 | {
268 | "type": "textRun",
269 | "textRun": {
270 | "text": "正文,这是正文,这个是正文,这个是正文啊。",
271 | "style": {},
272 | "location": {
273 | "zoneId": "0",
274 | "startIndex": 89,
275 | "endIndex": 110
276 | }
277 | }
278 | }
279 | ],
280 | "style": {},
281 | "location": {
282 | "zoneId": "0",
283 | "startIndex": 88,
284 | "endIndex": 110
285 | },
286 | "lineId": "9JeXmq"
287 | }
288 | },
289 | {
290 | "type": "paragraph",
291 | "paragraph": {
292 | "elements": [
293 | {
294 | "type": "textRun",
295 | "textRun": {
296 | "text": "正文,这是正文,这个是正文,这个是正文啊。正文,这是正文,这个是正文,这个是正文啊。正文,这是正文,这个是正文,这个是正文啊。正文,这是正文,这个是正文,这个是正文啊。正文,这是正文,这个是正文,这个是正文啊。正文,这是正文,这个是正文,这个是正文啊。正文,这是正文,这个是正文,这个是正文啊。",
297 | "style": {},
298 | "location": {
299 | "zoneId": "0",
300 | "startIndex": 112,
301 | "endIndex": 259
302 | }
303 | }
304 | }
305 | ],
306 | "style": {},
307 | "location": {
308 | "zoneId": "0",
309 | "startIndex": 111,
310 | "endIndex": 259
311 | },
312 | "lineId": "eDchaF"
313 | }
314 | },
315 | {
316 | "type": "paragraph",
317 | "paragraph": {
318 | "elements": [
319 | {
320 | "type": "textRun",
321 | "textRun": {
322 | "text": "列表",
323 | "style": {},
324 | "location": {
325 | "zoneId": "0",
326 | "startIndex": 261,
327 | "endIndex": 263
328 | }
329 | }
330 | }
331 | ],
332 | "style": {
333 | "headingLevel": 1
334 | },
335 | "location": {
336 | "zoneId": "0",
337 | "startIndex": 260,
338 | "endIndex": 263
339 | },
340 | "lineId": "Y2oAMb"
341 | }
342 | },
343 | {
344 | "type": "paragraph",
345 | "paragraph": {
346 | "elements": [
347 | {
348 | "type": "textRun",
349 | "textRun": {
350 | "text": "有序列表",
351 | "style": {},
352 | "location": {
353 | "zoneId": "0",
354 | "startIndex": 265,
355 | "endIndex": 269
356 | }
357 | }
358 | }
359 | ],
360 | "style": {
361 | "headingLevel": 2
362 | },
363 | "location": {
364 | "zoneId": "0",
365 | "startIndex": 264,
366 | "endIndex": 269
367 | },
368 | "lineId": "BofKka"
369 | }
370 | },
371 | {
372 | "type": "paragraph",
373 | "paragraph": {
374 | "elements": [
375 | {
376 | "type": "textRun",
377 | "textRun": {
378 | "text": "1",
379 | "style": {},
380 | "location": {
381 | "zoneId": "0",
382 | "startIndex": 271,
383 | "endIndex": 272
384 | }
385 | }
386 | }
387 | ],
388 | "style": {
389 | "list": {
390 | "type": "number",
391 | "indentLevel": 1,
392 | "number": 1
393 | }
394 | },
395 | "location": {
396 | "zoneId": "0",
397 | "startIndex": 270,
398 | "endIndex": 272
399 | },
400 | "lineId": "hyR5MJ"
401 | }
402 | },
403 | {
404 | "type": "paragraph",
405 | "paragraph": {
406 | "elements": [
407 | {
408 | "type": "textRun",
409 | "textRun": {
410 | "text": "A",
411 | "style": {},
412 | "location": {
413 | "zoneId": "0",
414 | "startIndex": 274,
415 | "endIndex": 275
416 | }
417 | }
418 | }
419 | ],
420 | "style": {
421 | "list": {
422 | "type": "number",
423 | "indentLevel": 2,
424 | "number": 1
425 | }
426 | },
427 | "location": {
428 | "zoneId": "0",
429 | "startIndex": 273,
430 | "endIndex": 275
431 | },
432 | "lineId": "eESxIU"
433 | }
434 | },
435 | {
436 | "type": "paragraph",
437 | "paragraph": {
438 | "elements": [
439 | {
440 | "type": "textRun",
441 | "textRun": {
442 | "text": "i",
443 | "style": {},
444 | "location": {
445 | "zoneId": "0",
446 | "startIndex": 277,
447 | "endIndex": 278
448 | }
449 | }
450 | }
451 | ],
452 | "style": {
453 | "list": {
454 | "type": "number",
455 | "indentLevel": 3,
456 | "number": 1
457 | }
458 | },
459 | "location": {
460 | "zoneId": "0",
461 | "startIndex": 276,
462 | "endIndex": 278
463 | },
464 | "lineId": "nWlL7c"
465 | }
466 | },
467 | {
468 | "type": "paragraph",
469 | "paragraph": {
470 | "elements": [
471 | {
472 | "type": "textRun",
473 | "textRun": {
474 | "text": "1",
475 | "style": {},
476 | "location": {
477 | "zoneId": "0",
478 | "startIndex": 280,
479 | "endIndex": 281
480 | }
481 | }
482 | }
483 | ],
484 | "style": {
485 | "list": {
486 | "type": "number",
487 | "indentLevel": 4,
488 | "number": 1
489 | }
490 | },
491 | "location": {
492 | "zoneId": "0",
493 | "startIndex": 279,
494 | "endIndex": 281
495 | },
496 | "lineId": "FtToyR"
497 | }
498 | },
499 | {
500 | "type": "paragraph",
501 | "paragraph": {
502 | "elements": [
503 | {
504 | "type": "textRun",
505 | "textRun": {
506 | "text": "a",
507 | "style": {},
508 | "location": {
509 | "zoneId": "0",
510 | "startIndex": 283,
511 | "endIndex": 284
512 | }
513 | }
514 | }
515 | ],
516 | "style": {
517 | "list": {
518 | "type": "number",
519 | "indentLevel": 5,
520 | "number": 1
521 | }
522 | },
523 | "location": {
524 | "zoneId": "0",
525 | "startIndex": 282,
526 | "endIndex": 284
527 | },
528 | "lineId": "uUw94E"
529 | }
530 | },
531 | {
532 | "type": "paragraph",
533 | "paragraph": {
534 | "elements": [
535 | {
536 | "type": "textRun",
537 | "textRun": {
538 | "text": "b",
539 | "style": {},
540 | "location": {
541 | "zoneId": "0",
542 | "startIndex": 286,
543 | "endIndex": 287
544 | }
545 | }
546 | }
547 | ],
548 | "style": {
549 | "list": {
550 | "type": "number",
551 | "indentLevel": 5,
552 | "number": 2
553 | }
554 | },
555 | "location": {
556 | "zoneId": "0",
557 | "startIndex": 285,
558 | "endIndex": 287
559 | },
560 | "lineId": "PtEfmX"
561 | }
562 | },
563 | {
564 | "type": "paragraph",
565 | "paragraph": {
566 | "elements": [
567 | {
568 | "type": "textRun",
569 | "textRun": {
570 | "text": "X",
571 | "style": {},
572 | "location": {
573 | "zoneId": "0",
574 | "startIndex": 289,
575 | "endIndex": 290
576 | }
577 | }
578 | }
579 | ],
580 | "style": {
581 | "list": {
582 | "type": "number",
583 | "indentLevel": 5,
584 | "number": 3
585 | }
586 | },
587 | "location": {
588 | "zoneId": "0",
589 | "startIndex": 288,
590 | "endIndex": 290
591 | },
592 | "lineId": "lCo4wo"
593 | }
594 | },
595 | {
596 | "type": "paragraph",
597 | "paragraph": {
598 | "elements": [
599 | {
600 | "type": "textRun",
601 | "textRun": {
602 | "text": "2",
603 | "style": {},
604 | "location": {
605 | "zoneId": "0",
606 | "startIndex": 292,
607 | "endIndex": 293
608 | }
609 | }
610 | }
611 | ],
612 | "style": {
613 | "list": {
614 | "type": "number",
615 | "indentLevel": 4,
616 | "number": 2
617 | }
618 | },
619 | "location": {
620 | "zoneId": "0",
621 | "startIndex": 291,
622 | "endIndex": 293
623 | },
624 | "lineId": "6CWfxH"
625 | }
626 | },
627 | {
628 | "type": "paragraph",
629 | "paragraph": {
630 | "elements": [
631 | {
632 | "type": "textRun",
633 | "textRun": {
634 | "text": "3",
635 | "style": {},
636 | "location": {
637 | "zoneId": "0",
638 | "startIndex": 295,
639 | "endIndex": 296
640 | }
641 | }
642 | }
643 | ],
644 | "style": {
645 | "list": {
646 | "type": "number",
647 | "indentLevel": 4,
648 | "number": 3
649 | }
650 | },
651 | "location": {
652 | "zoneId": "0",
653 | "startIndex": 294,
654 | "endIndex": 296
655 | },
656 | "lineId": "Gf7Blu"
657 | }
658 | },
659 | {
660 | "type": "paragraph",
661 | "paragraph": {
662 | "elements": [
663 | {
664 | "type": "textRun",
665 | "textRun": {
666 | "text": "Ii",
667 | "style": {},
668 | "location": {
669 | "zoneId": "0",
670 | "startIndex": 298,
671 | "endIndex": 300
672 | }
673 | }
674 | }
675 | ],
676 | "style": {
677 | "list": {
678 | "type": "number",
679 | "indentLevel": 3,
680 | "number": 2
681 | }
682 | },
683 | "location": {
684 | "zoneId": "0",
685 | "startIndex": 297,
686 | "endIndex": 300
687 | },
688 | "lineId": "l2hzDD"
689 | }
690 | },
691 | {
692 | "type": "paragraph",
693 | "paragraph": {
694 | "elements": [
695 | {
696 | "type": "textRun",
697 | "textRun": {
698 | "text": "Iii",
699 | "style": {},
700 | "location": {
701 | "zoneId": "0",
702 | "startIndex": 302,
703 | "endIndex": 305
704 | }
705 | }
706 | }
707 | ],
708 | "style": {
709 | "list": {
710 | "type": "number",
711 | "indentLevel": 3,
712 | "number": 3
713 | }
714 | },
715 | "location": {
716 | "zoneId": "0",
717 | "startIndex": 301,
718 | "endIndex": 305
719 | },
720 | "lineId": "foKYMi"
721 | }
722 | },
723 | {
724 | "type": "paragraph",
725 | "paragraph": {
726 | "elements": [
727 | {
728 | "type": "textRun",
729 | "textRun": {
730 | "text": "iv",
731 | "style": {},
732 | "location": {
733 | "zoneId": "0",
734 | "startIndex": 307,
735 | "endIndex": 309
736 | }
737 | }
738 | }
739 | ],
740 | "style": {
741 | "list": {
742 | "type": "number",
743 | "indentLevel": 3,
744 | "number": 4
745 | }
746 | },
747 | "location": {
748 | "zoneId": "0",
749 | "startIndex": 306,
750 | "endIndex": 309
751 | },
752 | "lineId": "BMG6Wk"
753 | }
754 | },
755 | {
756 | "type": "paragraph",
757 | "paragraph": {
758 | "elements": [
759 | {
760 | "type": "textRun",
761 | "textRun": {
762 | "text": "Dd",
763 | "style": {},
764 | "location": {
765 | "zoneId": "0",
766 | "startIndex": 311,
767 | "endIndex": 313
768 | }
769 | }
770 | }
771 | ],
772 | "style": {
773 | "list": {
774 | "type": "number",
775 | "indentLevel": 3,
776 | "number": 5
777 | }
778 | },
779 | "location": {
780 | "zoneId": "0",
781 | "startIndex": 310,
782 | "endIndex": 313
783 | },
784 | "lineId": "h6A0Un"
785 | }
786 | },
787 | {
788 | "type": "paragraph",
789 | "paragraph": {
790 | "elements": [
791 | {
792 | "type": "textRun",
793 | "textRun": {
794 | "text": "B",
795 | "style": {},
796 | "location": {
797 | "zoneId": "0",
798 | "startIndex": 315,
799 | "endIndex": 316
800 | }
801 | }
802 | }
803 | ],
804 | "style": {
805 | "list": {
806 | "type": "number",
807 | "indentLevel": 2,
808 | "number": 2
809 | }
810 | },
811 | "location": {
812 | "zoneId": "0",
813 | "startIndex": 314,
814 | "endIndex": 316
815 | },
816 | "lineId": "sWFyTC"
817 | }
818 | },
819 | {
820 | "type": "paragraph",
821 | "paragraph": {
822 | "elements": [
823 | {
824 | "type": "textRun",
825 | "textRun": {
826 | "text": "C",
827 | "style": {},
828 | "location": {
829 | "zoneId": "0",
830 | "startIndex": 318,
831 | "endIndex": 319
832 | }
833 | }
834 | }
835 | ],
836 | "style": {
837 | "list": {
838 | "type": "number",
839 | "indentLevel": 2,
840 | "number": 3
841 | }
842 | },
843 | "location": {
844 | "zoneId": "0",
845 | "startIndex": 317,
846 | "endIndex": 319
847 | },
848 | "lineId": "UUim3Q"
849 | }
850 | },
851 | {
852 | "type": "paragraph",
853 | "paragraph": {
854 | "elements": [
855 | {
856 | "type": "textRun",
857 | "textRun": {
858 | "text": "D",
859 | "style": {},
860 | "location": {
861 | "zoneId": "0",
862 | "startIndex": 321,
863 | "endIndex": 322
864 | }
865 | }
866 | }
867 | ],
868 | "style": {
869 | "list": {
870 | "type": "number",
871 | "indentLevel": 2,
872 | "number": 4
873 | }
874 | },
875 | "location": {
876 | "zoneId": "0",
877 | "startIndex": 320,
878 | "endIndex": 322
879 | },
880 | "lineId": "hs28H8"
881 | }
882 | },
883 | {
884 | "type": "paragraph",
885 | "paragraph": {
886 | "elements": [
887 | {
888 | "type": "textRun",
889 | "textRun": {
890 | "text": "E",
891 | "style": {},
892 | "location": {
893 | "zoneId": "0",
894 | "startIndex": 324,
895 | "endIndex": 325
896 | }
897 | }
898 | }
899 | ],
900 | "style": {
901 | "list": {
902 | "type": "number",
903 | "indentLevel": 2,
904 | "number": 5
905 | }
906 | },
907 | "location": {
908 | "zoneId": "0",
909 | "startIndex": 323,
910 | "endIndex": 325
911 | },
912 | "lineId": "hkfle8"
913 | }
914 | },
915 | {
916 | "type": "paragraph",
917 | "paragraph": {
918 | "elements": [
919 | {
920 | "type": "textRun",
921 | "textRun": {
922 | "text": "F",
923 | "style": {},
924 | "location": {
925 | "zoneId": "0",
926 | "startIndex": 327,
927 | "endIndex": 328
928 | }
929 | }
930 | }
931 | ],
932 | "style": {
933 | "list": {
934 | "type": "number",
935 | "indentLevel": 2,
936 | "number": 6
937 | }
938 | },
939 | "location": {
940 | "zoneId": "0",
941 | "startIndex": 326,
942 | "endIndex": 328
943 | },
944 | "lineId": "EpwoBT"
945 | }
946 | },
947 | {
948 | "type": "paragraph",
949 | "paragraph": {
950 | "elements": [
951 | {
952 | "type": "textRun",
953 | "textRun": {
954 | "text": "G",
955 | "style": {},
956 | "location": {
957 | "zoneId": "0",
958 | "startIndex": 330,
959 | "endIndex": 331
960 | }
961 | }
962 | }
963 | ],
964 | "style": {
965 | "list": {
966 | "type": "number",
967 | "indentLevel": 2,
968 | "number": 7
969 | }
970 | },
971 | "location": {
972 | "zoneId": "0",
973 | "startIndex": 329,
974 | "endIndex": 331
975 | },
976 | "lineId": "JKHlL4"
977 | }
978 | },
979 | {
980 | "type": "paragraph",
981 | "paragraph": {
982 | "elements": [
983 | {
984 | "type": "textRun",
985 | "textRun": {
986 | "text": "2",
987 | "style": {},
988 | "location": {
989 | "zoneId": "0",
990 | "startIndex": 333,
991 | "endIndex": 334
992 | }
993 | }
994 | }
995 | ],
996 | "style": {
997 | "list": {
998 | "type": "number",
999 | "indentLevel": 1,
1000 | "number": 2
1001 | }
1002 | },
1003 | "location": {
1004 | "zoneId": "0",
1005 | "startIndex": 332,
1006 | "endIndex": 334
1007 | },
1008 | "lineId": "oCwRKj"
1009 | }
1010 | },
1011 | {
1012 | "type": "paragraph",
1013 | "paragraph": {
1014 | "elements": [
1015 | {
1016 | "type": "textRun",
1017 | "textRun": {
1018 | "text": "3",
1019 | "style": {},
1020 | "location": {
1021 | "zoneId": "0",
1022 | "startIndex": 336,
1023 | "endIndex": 337
1024 | }
1025 | }
1026 | }
1027 | ],
1028 | "style": {
1029 | "list": {
1030 | "type": "number",
1031 | "indentLevel": 1,
1032 | "number": 3
1033 | }
1034 | },
1035 | "location": {
1036 | "zoneId": "0",
1037 | "startIndex": 335,
1038 | "endIndex": 337
1039 | },
1040 | "lineId": "mBS7x6"
1041 | }
1042 | },
1043 | {
1044 | "type": "paragraph",
1045 | "paragraph": {
1046 | "elements": [
1047 | {
1048 | "type": "textRun",
1049 | "textRun": {
1050 | "text": "无序列表",
1051 | "style": {},
1052 | "location": {
1053 | "zoneId": "0",
1054 | "startIndex": 339,
1055 | "endIndex": 343
1056 | }
1057 | }
1058 | }
1059 | ],
1060 | "style": {
1061 | "headingLevel": 2
1062 | },
1063 | "location": {
1064 | "zoneId": "0",
1065 | "startIndex": 338,
1066 | "endIndex": 343
1067 | },
1068 | "lineId": "cYJS3t"
1069 | }
1070 | },
1071 | {
1072 | "type": "paragraph",
1073 | "paragraph": {
1074 | "elements": [
1075 | {
1076 | "type": "textRun",
1077 | "textRun": {
1078 | "text": "X",
1079 | "style": {},
1080 | "location": {
1081 | "zoneId": "0",
1082 | "startIndex": 345,
1083 | "endIndex": 346
1084 | }
1085 | }
1086 | }
1087 | ],
1088 | "style": {
1089 | "list": {
1090 | "type": "bullet",
1091 | "indentLevel": 1
1092 | }
1093 | },
1094 | "location": {
1095 | "zoneId": "0",
1096 | "startIndex": 344,
1097 | "endIndex": 346
1098 | },
1099 | "lineId": "xkMy8J"
1100 | }
1101 | },
1102 | {
1103 | "type": "paragraph",
1104 | "paragraph": {
1105 | "elements": [
1106 | {
1107 | "type": "textRun",
1108 | "textRun": {
1109 | "text": "XX",
1110 | "style": {},
1111 | "location": {
1112 | "zoneId": "0",
1113 | "startIndex": 348,
1114 | "endIndex": 350
1115 | }
1116 | }
1117 | }
1118 | ],
1119 | "style": {
1120 | "list": {
1121 | "type": "bullet",
1122 | "indentLevel": 2
1123 | }
1124 | },
1125 | "location": {
1126 | "zoneId": "0",
1127 | "startIndex": 347,
1128 | "endIndex": 350
1129 | },
1130 | "lineId": "ZXtRun"
1131 | }
1132 | },
1133 | {
1134 | "type": "paragraph",
1135 | "paragraph": {
1136 | "elements": [
1137 | {
1138 | "type": "textRun",
1139 | "textRun": {
1140 | "text": "XXX",
1141 | "style": {},
1142 | "location": {
1143 | "zoneId": "0",
1144 | "startIndex": 352,
1145 | "endIndex": 355
1146 | }
1147 | }
1148 | }
1149 | ],
1150 | "style": {
1151 | "list": {
1152 | "type": "bullet",
1153 | "indentLevel": 3
1154 | }
1155 | },
1156 | "location": {
1157 | "zoneId": "0",
1158 | "startIndex": 351,
1159 | "endIndex": 355
1160 | },
1161 | "lineId": "xQs4TX"
1162 | }
1163 | },
1164 | {
1165 | "type": "paragraph",
1166 | "paragraph": {
1167 | "elements": [
1168 | {
1169 | "type": "textRun",
1170 | "textRun": {
1171 | "text": "XXX ",
1172 | "style": {},
1173 | "location": {
1174 | "zoneId": "0",
1175 | "startIndex": 357,
1176 | "endIndex": 361
1177 | }
1178 | }
1179 | }
1180 | ],
1181 | "style": {
1182 | "list": {
1183 | "type": "bullet",
1184 | "indentLevel": 4
1185 | }
1186 | },
1187 | "location": {
1188 | "zoneId": "0",
1189 | "startIndex": 356,
1190 | "endIndex": 361
1191 | },
1192 | "lineId": "5xwp5c"
1193 | }
1194 | },
1195 | {
1196 | "type": "paragraph",
1197 | "paragraph": {
1198 | "elements": [
1199 | {
1200 | "type": "textRun",
1201 | "textRun": {
1202 | "text": "XXXX",
1203 | "style": {},
1204 | "location": {
1205 | "zoneId": "0",
1206 | "startIndex": 363,
1207 | "endIndex": 367
1208 | }
1209 | }
1210 | }
1211 | ],
1212 | "style": {
1213 | "list": {
1214 | "type": "bullet",
1215 | "indentLevel": 5
1216 | }
1217 | },
1218 | "location": {
1219 | "zoneId": "0",
1220 | "startIndex": 362,
1221 | "endIndex": 367
1222 | },
1223 | "lineId": "9NPG1C"
1224 | }
1225 | },
1226 | {
1227 | "type": "paragraph",
1228 | "paragraph": {
1229 | "elements": [
1230 | {
1231 | "type": "textRun",
1232 | "textRun": {
1233 | "text": "X",
1234 | "style": {},
1235 | "location": {
1236 | "zoneId": "0",
1237 | "startIndex": 369,
1238 | "endIndex": 370
1239 | }
1240 | }
1241 | }
1242 | ],
1243 | "style": {
1244 | "list": {
1245 | "type": "bullet",
1246 | "indentLevel": 1
1247 | }
1248 | },
1249 | "location": {
1250 | "zoneId": "0",
1251 | "startIndex": 368,
1252 | "endIndex": 370
1253 | },
1254 | "lineId": "w6z89Q"
1255 | }
1256 | },
1257 | {
1258 | "type": "paragraph",
1259 | "paragraph": {
1260 | "elements": [
1261 | {
1262 | "type": "textRun",
1263 | "textRun": {
1264 | "text": "X",
1265 | "style": {},
1266 | "location": {
1267 | "zoneId": "0",
1268 | "startIndex": 372,
1269 | "endIndex": 373
1270 | }
1271 | }
1272 | }
1273 | ],
1274 | "style": {
1275 | "list": {
1276 | "type": "bullet",
1277 | "indentLevel": 1
1278 | }
1279 | },
1280 | "location": {
1281 | "zoneId": "0",
1282 | "startIndex": 371,
1283 | "endIndex": 373
1284 | },
1285 | "lineId": "WyvFcg"
1286 | }
1287 | },
1288 | {
1289 | "type": "paragraph",
1290 | "paragraph": {
1291 | "elements": [
1292 | {
1293 | "type": "textRun",
1294 | "textRun": {
1295 | "text": "任务列表",
1296 | "style": {},
1297 | "location": {
1298 | "zoneId": "0",
1299 | "startIndex": 375,
1300 | "endIndex": 379
1301 | }
1302 | }
1303 | }
1304 | ],
1305 | "style": {
1306 | "headingLevel": 1
1307 | },
1308 | "location": {
1309 | "zoneId": "0",
1310 | "startIndex": 374,
1311 | "endIndex": 379
1312 | },
1313 | "lineId": "WJNbbj"
1314 | }
1315 | },
1316 | {
1317 | "type": "paragraph",
1318 | "paragraph": {
1319 | "elements": [
1320 | {
1321 | "type": "textRun",
1322 | "textRun": {
1323 | "text": "任务 x",
1324 | "style": {},
1325 | "location": {
1326 | "zoneId": "0",
1327 | "startIndex": 381,
1328 | "endIndex": 385
1329 | }
1330 | }
1331 | }
1332 | ],
1333 | "style": {
1334 | "list": {
1335 | "type": "checkBox",
1336 | "indentLevel": 1
1337 | },
1338 | "todoUUID": "83d7cb7b-4e12-4da9-a884-789e57a61f53"
1339 | },
1340 | "location": {
1341 | "zoneId": "0",
1342 | "startIndex": 380,
1343 | "endIndex": 385
1344 | },
1345 | "lineId": "ix0zun"
1346 | }
1347 | },
1348 | {
1349 | "type": "paragraph",
1350 | "paragraph": {
1351 | "elements": [
1352 | {
1353 | "type": "textRun",
1354 | "textRun": {
1355 | "text": "任务 xx",
1356 | "style": {},
1357 | "location": {
1358 | "zoneId": "0",
1359 | "startIndex": 387,
1360 | "endIndex": 392
1361 | }
1362 | }
1363 | }
1364 | ],
1365 | "style": {
1366 | "list": {
1367 | "type": "checkBox",
1368 | "indentLevel": 2
1369 | },
1370 | "todoUUID": "f03cbebc-5c6c-4f39-8929-da5fb0b99660"
1371 | },
1372 | "location": {
1373 | "zoneId": "0",
1374 | "startIndex": 386,
1375 | "endIndex": 392
1376 | },
1377 | "lineId": "Lg7v5t"
1378 | }
1379 | },
1380 | {
1381 | "type": "paragraph",
1382 | "paragraph": {
1383 | "elements": [
1384 | {
1385 | "type": "textRun",
1386 | "textRun": {
1387 | "text": "任务 x",
1388 | "style": {},
1389 | "location": {
1390 | "zoneId": "0",
1391 | "startIndex": 394,
1392 | "endIndex": 398
1393 | }
1394 | }
1395 | }
1396 | ],
1397 | "style": {
1398 | "list": {
1399 | "type": "checkBox",
1400 | "indentLevel": 1
1401 | },
1402 | "todoUUID": "72983fbd-dc42-4a1a-a102-c60a3149dca0"
1403 | },
1404 | "location": {
1405 | "zoneId": "0",
1406 | "startIndex": 393,
1407 | "endIndex": 398
1408 | },
1409 | "lineId": "Wyu7D2"
1410 | }
1411 | },
1412 | {
1413 | "type": "paragraph",
1414 | "paragraph": {
1415 | "elements": [
1416 | {
1417 | "type": "textRun",
1418 | "textRun": {
1419 | "text": "完成的任务 x",
1420 | "style": {},
1421 | "location": {
1422 | "zoneId": "0",
1423 | "startIndex": 400,
1424 | "endIndex": 407
1425 | }
1426 | }
1427 | }
1428 | ],
1429 | "style": {
1430 | "list": {
1431 | "type": "checkedBox",
1432 | "indentLevel": 1
1433 | },
1434 | "todoUUID": "f652f07f-9d7e-409a-94c6-fac345298ec8"
1435 | },
1436 | "location": {
1437 | "zoneId": "0",
1438 | "startIndex": 399,
1439 | "endIndex": 407
1440 | },
1441 | "lineId": "8dkeY3"
1442 | }
1443 | },
1444 | {
1445 | "type": "paragraph",
1446 | "paragraph": {
1447 | "elements": [
1448 | {
1449 | "type": "textRun",
1450 | "textRun": {
1451 | "text": "高亮块",
1452 | "style": {},
1453 | "location": {
1454 | "zoneId": "0",
1455 | "startIndex": 409,
1456 | "endIndex": 412
1457 | }
1458 | }
1459 | }
1460 | ],
1461 | "style": {
1462 | "headingLevel": 1
1463 | },
1464 | "location": {
1465 | "zoneId": "0",
1466 | "startIndex": 408,
1467 | "endIndex": 412
1468 | },
1469 | "lineId": "af2U0l"
1470 | }
1471 | },
1472 | {
1473 | "type": "callout",
1474 | "callout": {
1475 | "location": {
1476 | "zoneId": "0",
1477 | "startIndex": 413,
1478 | "endIndex": 414
1479 | },
1480 | "calloutEmojiId": "exclamation",
1481 | "calloutBackgroundColor": {
1482 | "red": 246,
1483 | "green": 241,
1484 | "blue": 254,
1485 | "alpha": 1
1486 | },
1487 | "calloutBorderColor": {
1488 | "red": 205,
1489 | "green": 178,
1490 | "blue": 250,
1491 | "alpha": 1
1492 | },
1493 | "zoneId": "suv92xjkqr",
1494 | "body": {
1495 | "blocks": [
1496 | {
1497 | "type": "paragraph",
1498 | "paragraph": {
1499 | "elements": [
1500 | {
1501 | "type": "textRun",
1502 | "textRun": {
1503 | "text": "高亮块",
1504 | "style": {},
1505 | "location": {
1506 | "zoneId": "suv92xjkqr",
1507 | "startIndex": 1,
1508 | "endIndex": 4
1509 | }
1510 | }
1511 | }
1512 | ],
1513 | "style": {},
1514 | "location": {
1515 | "zoneId": "suv92xjkqr",
1516 | "startIndex": 0,
1517 | "endIndex": 4
1518 | },
1519 | "lineId": "NMGpSb"
1520 | }
1521 | },
1522 | {
1523 | "type": "paragraph",
1524 | "paragraph": {
1525 | "elements": [],
1526 | "style": {},
1527 | "location": {
1528 | "zoneId": "suv92xjkqr",
1529 | "startIndex": 5,
1530 | "endIndex": 6
1531 | },
1532 | "lineId": "oKhl46"
1533 | }
1534 | },
1535 | {
1536 | "type": "paragraph",
1537 | "paragraph": {
1538 | "elements": [
1539 | {
1540 | "type": "textRun",
1541 | "textRun": {
1542 | "text": "高亮块支持颜色,转成 Markdown 后不支持",
1543 | "style": {},
1544 | "location": {
1545 | "zoneId": "suv92xjkqr",
1546 | "startIndex": 8,
1547 | "endIndex": 32
1548 | }
1549 | }
1550 | }
1551 | ],
1552 | "style": {},
1553 | "location": {
1554 | "zoneId": "suv92xjkqr",
1555 | "startIndex": 7,
1556 | "endIndex": 32
1557 | },
1558 | "lineId": "8zkuoG"
1559 | }
1560 | }
1561 | ]
1562 | }
1563 | }
1564 | },
1565 | {
1566 | "type": "paragraph",
1567 | "paragraph": {
1568 | "elements": [
1569 | {
1570 | "type": "textRun",
1571 | "textRun": {
1572 | "text": "分割线",
1573 | "style": {},
1574 | "location": {
1575 | "zoneId": "0",
1576 | "startIndex": 416,
1577 | "endIndex": 419
1578 | }
1579 | }
1580 | }
1581 | ],
1582 | "style": {
1583 | "headingLevel": 1
1584 | },
1585 | "location": {
1586 | "zoneId": "0",
1587 | "startIndex": 415,
1588 | "endIndex": 419
1589 | },
1590 | "lineId": "8IGqPs"
1591 | }
1592 | },
1593 | {
1594 | "type": "horizontalLine",
1595 | "horizontalLine": {
1596 | "location": {
1597 | "zoneId": "0",
1598 | "startIndex": 420,
1599 | "endIndex": 422
1600 | }
1601 | }
1602 | },
1603 | {
1604 | "type": "paragraph",
1605 | "paragraph": {
1606 | "elements": [
1607 | {
1608 | "type": "textRun",
1609 | "textRun": {
1610 | "text": "引用",
1611 | "style": {},
1612 | "location": {
1613 | "zoneId": "0",
1614 | "startIndex": 424,
1615 | "endIndex": 426
1616 | }
1617 | }
1618 | }
1619 | ],
1620 | "style": {
1621 | "headingLevel": 1
1622 | },
1623 | "location": {
1624 | "zoneId": "0",
1625 | "startIndex": 423,
1626 | "endIndex": 426
1627 | },
1628 | "lineId": "luc8JM"
1629 | }
1630 | },
1631 | {
1632 | "type": "paragraph",
1633 | "paragraph": {
1634 | "elements": [
1635 | {
1636 | "type": "textRun",
1637 | "textRun": {
1638 | "text": "这是一个引用",
1639 | "style": {},
1640 | "location": {
1641 | "zoneId": "0",
1642 | "startIndex": 428,
1643 | "endIndex": 434
1644 | }
1645 | }
1646 | }
1647 | ],
1648 | "style": {
1649 | "quote": true
1650 | },
1651 | "location": {
1652 | "zoneId": "0",
1653 | "startIndex": 427,
1654 | "endIndex": 434
1655 | },
1656 | "lineId": "FBPOmk"
1657 | }
1658 | },
1659 | {
1660 | "type": "paragraph",
1661 | "paragraph": {
1662 | "elements": [],
1663 | "style": {},
1664 | "location": {
1665 | "zoneId": "0",
1666 | "startIndex": 435,
1667 | "endIndex": 436
1668 | },
1669 | "lineId": "TG3tDF"
1670 | }
1671 | },
1672 | {
1673 | "type": "paragraph",
1674 | "paragraph": {
1675 | "elements": [
1676 | {
1677 | "type": "textRun",
1678 | "textRun": {
1679 | "text": "这是一个引用,有 tab",
1680 | "style": {},
1681 | "location": {
1682 | "zoneId": "0",
1683 | "startIndex": 438,
1684 | "endIndex": 450
1685 | }
1686 | }
1687 | }
1688 | ],
1689 | "style": {
1690 | "quote": true
1691 | },
1692 | "location": {
1693 | "zoneId": "0",
1694 | "startIndex": 437,
1695 | "endIndex": 450
1696 | },
1697 | "lineId": "x2jzzb"
1698 | }
1699 | },
1700 | {
1701 | "type": "paragraph",
1702 | "paragraph": {
1703 | "elements": [],
1704 | "style": {},
1705 | "location": {
1706 | "zoneId": "0",
1707 | "startIndex": 451,
1708 | "endIndex": 452
1709 | },
1710 | "lineId": "YbH3IU"
1711 | }
1712 | },
1713 | {
1714 | "type": "paragraph",
1715 | "paragraph": {
1716 | "elements": [
1717 | {
1718 | "type": "textRun",
1719 | "textRun": {
1720 | "text": "引用行 1",
1721 | "style": {},
1722 | "location": {
1723 | "zoneId": "0",
1724 | "startIndex": 454,
1725 | "endIndex": 459
1726 | }
1727 | }
1728 | }
1729 | ],
1730 | "style": {
1731 | "quote": true
1732 | },
1733 | "location": {
1734 | "zoneId": "0",
1735 | "startIndex": 453,
1736 | "endIndex": 459
1737 | },
1738 | "lineId": "eHESfV"
1739 | }
1740 | },
1741 | {
1742 | "type": "paragraph",
1743 | "paragraph": {
1744 | "elements": [
1745 | {
1746 | "type": "textRun",
1747 | "textRun": {
1748 | "text": "引用行 2",
1749 | "style": {},
1750 | "location": {
1751 | "zoneId": "0",
1752 | "startIndex": 461,
1753 | "endIndex": 466
1754 | }
1755 | }
1756 | }
1757 | ],
1758 | "style": {
1759 | "quote": true
1760 | },
1761 | "location": {
1762 | "zoneId": "0",
1763 | "startIndex": 460,
1764 | "endIndex": 466
1765 | },
1766 | "lineId": "ARhcPm"
1767 | }
1768 | },
1769 | {
1770 | "type": "paragraph",
1771 | "paragraph": {
1772 | "elements": [
1773 | {
1774 | "type": "textRun",
1775 | "textRun": {
1776 | "text": "引用行 3",
1777 | "style": {},
1778 | "location": {
1779 | "zoneId": "0",
1780 | "startIndex": 468,
1781 | "endIndex": 473
1782 | }
1783 | }
1784 | }
1785 | ],
1786 | "style": {
1787 | "quote": true
1788 | },
1789 | "location": {
1790 | "zoneId": "0",
1791 | "startIndex": 467,
1792 | "endIndex": 473
1793 | },
1794 | "lineId": "GPapOS"
1795 | }
1796 | },
1797 | {
1798 | "type": "paragraph",
1799 | "paragraph": {
1800 | "elements": [],
1801 | "style": {},
1802 | "location": {
1803 | "zoneId": "0",
1804 | "startIndex": 474,
1805 | "endIndex": 475
1806 | },
1807 | "lineId": "8nzIdP"
1808 | }
1809 | },
1810 | {
1811 | "type": "paragraph",
1812 | "paragraph": {
1813 | "elements": [
1814 | {
1815 | "type": "textRun",
1816 | "textRun": {
1817 | "text": "代码块",
1818 | "style": {},
1819 | "location": {
1820 | "zoneId": "0",
1821 | "startIndex": 477,
1822 | "endIndex": 480
1823 | }
1824 | }
1825 | }
1826 | ],
1827 | "style": {
1828 | "headingLevel": 1
1829 | },
1830 | "location": {
1831 | "zoneId": "0",
1832 | "startIndex": 476,
1833 | "endIndex": 480
1834 | },
1835 | "lineId": "YXUEDz"
1836 | }
1837 | },
1838 | {
1839 | "type": "code",
1840 | "code": {
1841 | "language": "Go",
1842 | "location": {
1843 | "zoneId": "0",
1844 | "startIndex": 481,
1845 | "endIndex": 482
1846 | },
1847 | "zoneId": "kmeduldfp7",
1848 | "body": {
1849 | "blocks": [
1850 | {
1851 | "type": "paragraph",
1852 | "paragraph": {
1853 | "elements": [
1854 | {
1855 | "type": "textRun",
1856 | "textRun": {
1857 | "text": "func f() {",
1858 | "style": {},
1859 | "location": {
1860 | "zoneId": "kmeduldfp7",
1861 | "startIndex": 0,
1862 | "endIndex": 10
1863 | }
1864 | }
1865 | }
1866 | ],
1867 | "location": {
1868 | "zoneId": "kmeduldfp7",
1869 | "startIndex": 0,
1870 | "endIndex": 10
1871 | },
1872 | "lineId": "mgPCAK"
1873 | }
1874 | },
1875 | {
1876 | "type": "paragraph",
1877 | "paragraph": {
1878 | "elements": [
1879 | {
1880 | "type": "textRun",
1881 | "textRun": {
1882 | "text": "// do sth",
1883 | "style": {},
1884 | "location": {
1885 | "zoneId": "kmeduldfp7",
1886 | "startIndex": 12,
1887 | "endIndex": 21
1888 | }
1889 | }
1890 | }
1891 | ],
1892 | "style": {},
1893 | "location": {
1894 | "zoneId": "kmeduldfp7",
1895 | "startIndex": 11,
1896 | "endIndex": 21
1897 | },
1898 | "lineId": "OVqoih"
1899 | }
1900 | },
1901 | {
1902 | "type": "paragraph",
1903 | "paragraph": {
1904 | "elements": [
1905 | {
1906 | "type": "textRun",
1907 | "textRun": {
1908 | "text": "}",
1909 | "style": {},
1910 | "location": {
1911 | "zoneId": "kmeduldfp7",
1912 | "startIndex": 23,
1913 | "endIndex": 24
1914 | }
1915 | }
1916 | }
1917 | ],
1918 | "style": {},
1919 | "location": {
1920 | "zoneId": "kmeduldfp7",
1921 | "startIndex": 22,
1922 | "endIndex": 24
1923 | },
1924 | "lineId": "UmeYix"
1925 | }
1926 | }
1927 | ]
1928 | }
1929 | }
1930 | },
1931 | {
1932 | "type": "paragraph",
1933 | "paragraph": {
1934 | "elements": [
1935 | {
1936 | "type": "textRun",
1937 | "textRun": {
1938 | "text": "图片",
1939 | "style": {},
1940 | "location": {
1941 | "zoneId": "0",
1942 | "startIndex": 484,
1943 | "endIndex": 486
1944 | }
1945 | }
1946 | }
1947 | ],
1948 | "style": {
1949 | "headingLevel": 1
1950 | },
1951 | "location": {
1952 | "zoneId": "0",
1953 | "startIndex": 483,
1954 | "endIndex": 486
1955 | },
1956 | "lineId": "GDaiFX"
1957 | }
1958 | },
1959 | {
1960 | "type": "paragraph",
1961 | "paragraph": {
1962 | "elements": [
1963 | {
1964 | "type": "textRun",
1965 | "textRun": {
1966 | "text": "一个图片",
1967 | "style": {},
1968 | "location": {
1969 | "zoneId": "0",
1970 | "startIndex": 488,
1971 | "endIndex": 492
1972 | }
1973 | }
1974 | }
1975 | ],
1976 | "style": {
1977 | "headingLevel": 2
1978 | },
1979 | "location": {
1980 | "zoneId": "0",
1981 | "startIndex": 487,
1982 | "endIndex": 492
1983 | },
1984 | "lineId": "4s7vmw"
1985 | }
1986 | },
1987 | {
1988 | "type": "gallery",
1989 | "gallery": {
1990 | "galleryStyle": {},
1991 | "imageList": [
1992 | {
1993 | "fileToken": "boxcnyAEhNeanmSz2XhcK7ata0t",
1994 | "width": 1536,
1995 | "height": 322
1996 | }
1997 | ],
1998 | "location": {
1999 | "zoneId": "0",
2000 | "startIndex": 493,
2001 | "endIndex": 495
2002 | }
2003 | }
2004 | },
2005 | {
2006 | "type": "paragraph",
2007 | "paragraph": {
2008 | "elements": [
2009 | {
2010 | "type": "textRun",
2011 | "textRun": {
2012 | "text": "并排图片",
2013 | "style": {},
2014 | "location": {
2015 | "zoneId": "0",
2016 | "startIndex": 497,
2017 | "endIndex": 501
2018 | }
2019 | }
2020 | }
2021 | ],
2022 | "style": {
2023 | "headingLevel": 2
2024 | },
2025 | "location": {
2026 | "zoneId": "0",
2027 | "startIndex": 496,
2028 | "endIndex": 501
2029 | },
2030 | "lineId": "q69lzO"
2031 | }
2032 | },
2033 | {
2034 | "type": "gallery",
2035 | "gallery": {
2036 | "galleryStyle": {},
2037 | "imageList": [
2038 | {
2039 | "fileToken": "boxcnx060XAN4NUm2doWRuGToWr",
2040 | "width": 332,
2041 | "height": 452
2042 | },
2043 | {
2044 | "fileToken": "boxcniB7OYCR0mmRx0kBAcfbZmc",
2045 | "width": 392,
2046 | "height": 452
2047 | }
2048 | ],
2049 | "location": {
2050 | "zoneId": "0",
2051 | "startIndex": 502,
2052 | "endIndex": 505
2053 | }
2054 | }
2055 | },
2056 | {
2057 | "type": "paragraph",
2058 | "paragraph": {
2059 | "elements": [],
2060 | "location": {
2061 | "zoneId": "0",
2062 | "startIndex": 506,
2063 | "endIndex": 506
2064 | },
2065 | "lineId": "F1PKvG"
2066 | }
2067 | },
2068 | {
2069 | "type": "paragraph",
2070 | "paragraph": {
2071 | "elements": [
2072 | {
2073 | "type": "textRun",
2074 | "textRun": {
2075 | "text": "表格",
2076 | "style": {},
2077 | "location": {
2078 | "zoneId": "0",
2079 | "startIndex": 508,
2080 | "endIndex": 510
2081 | }
2082 | }
2083 | }
2084 | ],
2085 | "style": {
2086 | "headingLevel": 1
2087 | },
2088 | "location": {
2089 | "zoneId": "0",
2090 | "startIndex": 507,
2091 | "endIndex": 510
2092 | },
2093 | "lineId": "BXyd1I"
2094 | }
2095 | },
2096 | {
2097 | "type": "table",
2098 | "table": {
2099 | "tableId": "rs8vji1tokd8n9bl42jcndj0mmkjqsmsku-cs2j1enfcdj297uqvb6lq56qc5qoiasmb4",
2100 | "rowSize": 2,
2101 | "columnSize": 3,
2102 | "tableRows": [
2103 | {
2104 | "rowIndex": 0,
2105 | "tableCells": [
2106 | {
2107 | "zoneId": "xr1piaaher33bi4ad95vbvp508svs5cwb7vxc18mdhniulp2dj2zvb984e5dju8aytf4pm",
2108 | "columnIndex": 0,
2109 | "body": {
2110 | "blocks": [
2111 | {
2112 | "type": "paragraph",
2113 | "paragraph": {
2114 | "elements": [
2115 | {
2116 | "type": "textRun",
2117 | "textRun": {
2118 | "text": "x1.y1",
2119 | "style": {},
2120 | "location": {
2121 | "zoneId": "xr1piaaher33bi4ad95vbvp508svs5cwb7vxc18mdhniulp2dj2zvb984e5dju8aytf4pm",
2122 | "startIndex": 0,
2123 | "endIndex": 5
2124 | }
2125 | }
2126 | }
2127 | ],
2128 | "location": {
2129 | "zoneId": "xr1piaaher33bi4ad95vbvp508svs5cwb7vxc18mdhniulp2dj2zvb984e5dju8aytf4pm",
2130 | "startIndex": 0,
2131 | "endIndex": 5
2132 | }
2133 | }
2134 | }
2135 | ]
2136 | }
2137 | },
2138 | {
2139 | "zoneId": "xr1piaaher33bi4ad95vbvp508svs5cwb7vxc1ruer47l0w0znahmby2vf82fs025qqrh1",
2140 | "columnIndex": 1,
2141 | "body": {
2142 | "blocks": [
2143 | {
2144 | "type": "paragraph",
2145 | "paragraph": {
2146 | "elements": [
2147 | {
2148 | "type": "textRun",
2149 | "textRun": {
2150 | "text": "x2.y1",
2151 | "style": {},
2152 | "location": {
2153 | "zoneId": "xr1piaaher33bi4ad95vbvp508svs5cwb7vxc1ruer47l0w0znahmby2vf82fs025qqrh1",
2154 | "startIndex": 0,
2155 | "endIndex": 5
2156 | }
2157 | }
2158 | }
2159 | ],
2160 | "location": {
2161 | "zoneId": "xr1piaaher33bi4ad95vbvp508svs5cwb7vxc1ruer47l0w0znahmby2vf82fs025qqrh1",
2162 | "startIndex": 0,
2163 | "endIndex": 5
2164 | },
2165 | "lineId": "PqqSHc"
2166 | }
2167 | }
2168 | ]
2169 | }
2170 | },
2171 | {
2172 | "zoneId": "xr1piaaher33bi4ad95vbvp508svs5cwb7vxc1k615ppodh0mnjeqcqwvzgq2tlyqfefhl",
2173 | "columnIndex": 2,
2174 | "body": {
2175 | "blocks": [
2176 | {
2177 | "type": "paragraph",
2178 | "paragraph": {
2179 | "elements": [
2180 | {
2181 | "type": "textRun",
2182 | "textRun": {
2183 | "text": "x3.y1",
2184 | "style": {},
2185 | "location": {
2186 | "zoneId": "xr1piaaher33bi4ad95vbvp508svs5cwb7vxc1k615ppodh0mnjeqcqwvzgq2tlyqfefhl",
2187 | "startIndex": 0,
2188 | "endIndex": 5
2189 | }
2190 | }
2191 | }
2192 | ],
2193 | "location": {
2194 | "zoneId": "xr1piaaher33bi4ad95vbvp508svs5cwb7vxc1k615ppodh0mnjeqcqwvzgq2tlyqfefhl",
2195 | "startIndex": 0,
2196 | "endIndex": 5
2197 | },
2198 | "lineId": "w7uf6j"
2199 | }
2200 | }
2201 | ]
2202 | }
2203 | }
2204 | ]
2205 | },
2206 | {
2207 | "rowIndex": 1,
2208 | "tableCells": [
2209 | {
2210 | "zoneId": "xr1ipuesurh0nzgi1j88te8z3uen6w9852uxc18mdhniulp2dj2zvb984e5dju8aytf4pm",
2211 | "columnIndex": 0,
2212 | "body": {
2213 | "blocks": [
2214 | {
2215 | "type": "paragraph",
2216 | "paragraph": {
2217 | "elements": [
2218 | {
2219 | "type": "textRun",
2220 | "textRun": {
2221 | "text": "x1.y2",
2222 | "style": {},
2223 | "location": {
2224 | "zoneId": "xr1ipuesurh0nzgi1j88te8z3uen6w9852uxc18mdhniulp2dj2zvb984e5dju8aytf4pm",
2225 | "startIndex": 0,
2226 | "endIndex": 5
2227 | }
2228 | }
2229 | }
2230 | ],
2231 | "location": {
2232 | "zoneId": "xr1ipuesurh0nzgi1j88te8z3uen6w9852uxc18mdhniulp2dj2zvb984e5dju8aytf4pm",
2233 | "startIndex": 0,
2234 | "endIndex": 5
2235 | },
2236 | "lineId": "90XYiS"
2237 | }
2238 | }
2239 | ]
2240 | }
2241 | },
2242 | {
2243 | "zoneId": "xr1ipuesurh0nzgi1j88te8z3uen6w9852uxc1ruer47l0w0znahmby2vf82fs025qqrh1",
2244 | "columnIndex": 1,
2245 | "body": {
2246 | "blocks": [
2247 | {
2248 | "type": "paragraph",
2249 | "paragraph": {
2250 | "elements": [
2251 | {
2252 | "type": "textRun",
2253 | "textRun": {
2254 | "text": "x2.y2",
2255 | "style": {},
2256 | "location": {
2257 | "zoneId": "xr1ipuesurh0nzgi1j88te8z3uen6w9852uxc1ruer47l0w0znahmby2vf82fs025qqrh1",
2258 | "startIndex": 0,
2259 | "endIndex": 5
2260 | }
2261 | }
2262 | }
2263 | ],
2264 | "location": {
2265 | "zoneId": "xr1ipuesurh0nzgi1j88te8z3uen6w9852uxc1ruer47l0w0znahmby2vf82fs025qqrh1",
2266 | "startIndex": 0,
2267 | "endIndex": 5
2268 | },
2269 | "lineId": "lb3jJb"
2270 | }
2271 | }
2272 | ]
2273 | }
2274 | },
2275 | {
2276 | "zoneId": "xr1ipuesurh0nzgi1j88te8z3uen6w9852uxc1k615ppodh0mnjeqcqwvzgq2tlyqfefhl",
2277 | "columnIndex": 2,
2278 | "body": {
2279 | "blocks": [
2280 | {
2281 | "type": "paragraph",
2282 | "paragraph": {
2283 | "elements": [
2284 | {
2285 | "type": "textRun",
2286 | "textRun": {
2287 | "text": "x3.y2",
2288 | "style": {},
2289 | "location": {
2290 | "zoneId": "xr1ipuesurh0nzgi1j88te8z3uen6w9852uxc1k615ppodh0mnjeqcqwvzgq2tlyqfefhl",
2291 | "startIndex": 0,
2292 | "endIndex": 5
2293 | }
2294 | }
2295 | }
2296 | ],
2297 | "location": {
2298 | "zoneId": "xr1ipuesurh0nzgi1j88te8z3uen6w9852uxc1k615ppodh0mnjeqcqwvzgq2tlyqfefhl",
2299 | "startIndex": 0,
2300 | "endIndex": 5
2301 | },
2302 | "lineId": "cWnsQz"
2303 | }
2304 | }
2305 | ]
2306 | }
2307 | }
2308 | ]
2309 | }
2310 | ],
2311 | "tableStyle": {
2312 | "tableColumnProperties": [
2313 | {
2314 | "width": 100
2315 | },
2316 | {
2317 | "width": 100
2318 | },
2319 | {
2320 | "width": 100
2321 | }
2322 | ]
2323 | },
2324 | "mergedCells": [],
2325 | "location": {
2326 | "zoneId": "0",
2327 | "startIndex": 511,
2328 | "endIndex": 513
2329 | }
2330 | }
2331 | },
2332 | {
2333 | "type": "paragraph",
2334 | "paragraph": {
2335 | "elements": [
2336 | {
2337 | "type": "textRun",
2338 | "textRun": {
2339 | "text": "电子表格",
2340 | "style": {},
2341 | "location": {
2342 | "zoneId": "0",
2343 | "startIndex": 515,
2344 | "endIndex": 519
2345 | }
2346 | }
2347 | }
2348 | ],
2349 | "style": {
2350 | "headingLevel": 1
2351 | },
2352 | "location": {
2353 | "zoneId": "0",
2354 | "startIndex": 514,
2355 | "endIndex": 519
2356 | },
2357 | "lineId": "4Jz3RQ"
2358 | }
2359 | },
2360 | {
2361 | "type": "sheet",
2362 | "sheet": {
2363 | "token": "shtcnVZBJ1F05uW16LwcibZDJdf_8OPm5F",
2364 | "location": {
2365 | "zoneId": "0",
2366 | "startIndex": 520,
2367 | "endIndex": 522
2368 | }
2369 | }
2370 | },
2371 | {
2372 | "type": "paragraph",
2373 | "paragraph": {
2374 | "elements": [
2375 | {
2376 | "type": "textRun",
2377 | "textRun": {
2378 | "text": "链接",
2379 | "style": {},
2380 | "location": {
2381 | "zoneId": "0",
2382 | "startIndex": 524,
2383 | "endIndex": 526
2384 | }
2385 | }
2386 | }
2387 | ],
2388 | "style": {
2389 | "headingLevel": 1
2390 | },
2391 | "location": {
2392 | "zoneId": "0",
2393 | "startIndex": 523,
2394 | "endIndex": 526
2395 | },
2396 | "lineId": "XHyVHE"
2397 | }
2398 | },
2399 | {
2400 | "type": "paragraph",
2401 | "paragraph": {
2402 | "elements": [
2403 | {
2404 | "type": "textRun",
2405 | "textRun": {
2406 | "text": "链接文本",
2407 | "style": {
2408 | "link": {
2409 | "url": "https%3A%2F%2Fply.readthedocs.io%2Fen%2Flatest%2Fply.html"
2410 | }
2411 | },
2412 | "location": {
2413 | "zoneId": "0",
2414 | "startIndex": 528,
2415 | "endIndex": 532
2416 | }
2417 | }
2418 | }
2419 | ],
2420 | "style": {},
2421 | "location": {
2422 | "zoneId": "0",
2423 | "startIndex": 527,
2424 | "endIndex": 532
2425 | },
2426 | "lineId": "3yjsF6"
2427 | }
2428 | },
2429 | {
2430 | "type": "paragraph",
2431 | "paragraph": {
2432 | "elements": [
2433 | {
2434 | "type": "textRun",
2435 | "textRun": {
2436 | "text": "网页卡片",
2437 | "style": {},
2438 | "location": {
2439 | "zoneId": "0",
2440 | "startIndex": 534,
2441 | "endIndex": 538
2442 | }
2443 | }
2444 | }
2445 | ],
2446 | "style": {
2447 | "headingLevel": 1
2448 | },
2449 | "location": {
2450 | "zoneId": "0",
2451 | "startIndex": 533,
2452 | "endIndex": 538
2453 | },
2454 | "lineId": "LyC1CF"
2455 | }
2456 | },
2457 | {
2458 | "type": "undefinedBlock",
2459 | "undefinedBlock": {
2460 | "location": {
2461 | "zoneId": "0",
2462 | "startIndex": 539,
2463 | "endIndex": 541
2464 | }
2465 | }
2466 | },
2467 | {
2468 | "type": "paragraph",
2469 | "paragraph": {
2470 | "elements": [
2471 | {
2472 | "type": "textRun",
2473 | "textRun": {
2474 | "text": "云文档",
2475 | "style": {},
2476 | "location": {
2477 | "zoneId": "0",
2478 | "startIndex": 543,
2479 | "endIndex": 546
2480 | }
2481 | }
2482 | }
2483 | ],
2484 | "style": {
2485 | "headingLevel": 1
2486 | },
2487 | "location": {
2488 | "zoneId": "0",
2489 | "startIndex": 542,
2490 | "endIndex": 546
2491 | },
2492 | "lineId": "xWRS5q"
2493 | }
2494 | },
2495 | {
2496 | "type": "paragraph",
2497 | "paragraph": {
2498 | "elements": [
2499 | {
2500 | "type": "docsLink",
2501 | "docsLink": {
2502 | "url": "https://rs6qnacjws.feishu.cn/docs/doccnKOgFFoPz5Z1OZ5wU9H7sdf",
2503 | "location": {
2504 | "zoneId": "0",
2505 | "startIndex": 547,
2506 | "endIndex": 559
2507 | }
2508 | }
2509 | }
2510 | ],
2511 | "location": {
2512 | "zoneId": "0",
2513 | "startIndex": 547,
2514 | "endIndex": 559
2515 | },
2516 | "lineId": "T6caa5"
2517 | }
2518 | },
2519 | {
2520 | "type": "paragraph",
2521 | "paragraph": {
2522 | "elements": [
2523 | {
2524 | "type": "textRun",
2525 | "textRun": {
2526 | "text": "群名片",
2527 | "style": {},
2528 | "location": {
2529 | "zoneId": "0",
2530 | "startIndex": 561,
2531 | "endIndex": 564
2532 | }
2533 | }
2534 | }
2535 | ],
2536 | "style": {
2537 | "headingLevel": 1
2538 | },
2539 | "location": {
2540 | "zoneId": "0",
2541 | "startIndex": 560,
2542 | "endIndex": 564
2543 | },
2544 | "lineId": "QGxelY"
2545 | }
2546 | },
2547 | {
2548 | "type": "chatGroup",
2549 | "chatGroup": {
2550 | "openChatId": "oc_e5dc4d726035aff7317c168440ed5b5b",
2551 | "location": {
2552 | "zoneId": "0",
2553 | "startIndex": 565,
2554 | "endIndex": 567
2555 | }
2556 | }
2557 | },
2558 | {
2559 | "type": "paragraph",
2560 | "paragraph": {
2561 | "elements": [
2562 | {
2563 | "type": "textRun",
2564 | "textRun": {
2565 | "text": "文件",
2566 | "style": {},
2567 | "location": {
2568 | "zoneId": "0",
2569 | "startIndex": 569,
2570 | "endIndex": 571
2571 | }
2572 | }
2573 | }
2574 | ],
2575 | "style": {
2576 | "headingLevel": 1
2577 | },
2578 | "location": {
2579 | "zoneId": "0",
2580 | "startIndex": 568,
2581 | "endIndex": 571
2582 | },
2583 | "lineId": "VHuRJX"
2584 | }
2585 | },
2586 | {
2587 | "type": "file",
2588 | "file": {
2589 | "fileToken": "boxcnBne2oNxLjcnSTFURxU0czv",
2590 | "viewType": "card",
2591 | "fileName": "pending.png",
2592 | "location": {
2593 | "zoneId": "0",
2594 | "startIndex": 572,
2595 | "endIndex": 574
2596 | }
2597 | }
2598 | },
2599 | {
2600 | "type": "paragraph",
2601 | "paragraph": {
2602 | "elements": [],
2603 | "location": {
2604 | "zoneId": "0",
2605 | "startIndex": 575,
2606 | "endIndex": 575
2607 | },
2608 | "lineId": "Xq8AiE"
2609 | }
2610 | }
2611 | ]
2612 | }
2613 | }
2614 |
--------------------------------------------------------------------------------