ob-jq

1
2
3
{"a": "test"}

.a

Restclient

基础用法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# -*- restclient -*-
#
# Gets  all Github APIs, formats JSON, shows response status and headers underneath.
# Also sends a User-Agent header, because the Github API requires this.
#
GET https://api.github.com
User-Agent: Emacs Restclient

#
# It can even show an image!
#
GET http://upload.wikimedia.org/wikipedia/commons/6/63/Wikipedia-logo.png

#
# A bit of json GET, you can pass headers too
#
GET http://jira.atlassian.com/rest/api/latest/issue/JRA-9
User-Agent: Emacs24
Accept-Encoding: compress, gzip


#
# Post works too, entity just goes after an empty line. Same is for PUT.
# 请求数据
#
POST https://jira.atlassian.com/rest/api/2/search
Content-Type: application/json

{
        "jql": "project = HCPUB",
        "startAt": 0,
        "maxResults": 15,
        "fields": [
                "summary",
                "status",
                "assignee"
        ]
}

删除:

1
2
3
4
#
# And delete, will return not-found error...
#
DELETE https://jira.atlassian.com/rest/api/2/version/20

设置变量:

1
2
3
# Set a variable to the value of your ip address using a jq expression
GET http://httpbin.org/ip
-> jq-set-var :my-ip .origin

变量

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# :myvar = the value
# :myvar := (some (artbitrary 'elisp)

# 多行
:myvar = <<
Authorization: :my-auth
Content-Type: application/json
User-Agent: SomeApp/1.0
#

# 或使用 lisp,要以 # 结束
:myvar := <<
(some-long-elisp
    (code spanning many lines)
#

使用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# Some generic vars

:my-auth = 319854857345898457457
:my-headers = <<
Authorization: :my-auth
Content-Type: application/json
User-Agent: SomeApp/1.0
#

# Update a user's name

:user-id = 7
:the-name := (format "%s %s %d" 'Neo (md5 "The Chosen") (+ 100 1))

PUT http://localhost:4000/users/:user-id/
:my-headers

{ "name": ":the-name" }

测试:

取单个用户

1
2
3
4
:origin = https://reqres.in

# get single user by id=2
GET :origin/api/users/2

创建用户

1
2
3
4
5
6
# create user
:origin = https://reqres.in

POST :origin/api/users

{ "name": "test", "job": "test" }

Verb

Examples

/img/emacs/emacs-verb.svg

Response Buffer

Response Buffer 的内容类型主要由 Content-Type 和 verb-content-type-handlers 的 内容决定,而字符编码要么是用 Content-Type 中指定的要么是 verb-default-response-charset 的值,默认是 utf-8

而类型主要就两种, Text 和 Binary, 文本会根据 charset 来进行解码后显示,对于二 进制内容则使用 emacs 内置能力直接显示。

verb-content-type-handlers 的值:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
;; Value
(setq verb-content-type-handlers
      '(("text/html" html-mode)
        ("\\(application\\|text\\)/xml" xml-mode)
        ("application/xhtml\\+xml" xml-mode)
        ("application/json" verb-handler-json)
        ("application/javascript" js-mode)
        ("application/css" css-mode)
        ("text/plain" text-mode)
        ("application/pdf" doc-view-mode t)
        ("image/png" image-mode t)
        ("image/svg\\+xml" image-mode t)
        ("image/x-windows-bmp" image-mode t)
        ("image/gif" image-mode t)
        ("image/jpe?g" image-mode t)))

关闭 Response Buffer 两个函数:

verb-kill-response-buffer-and-window, <C-c C-r C-k> 关闭当前。

verb-kill-all-response-buffers, <C-c C-r C-a> 关闭所有。

重新发送请求: verb-re-send-request, <C-c C-r r>

如果在 Response Buffer 中想查看请求内容可以使用:

verb-show-request, <C-c C-r C-q>

verb-toggle-show-headers, <C-c C-r C-h>

Request Headers   verb

1
2
3
get https://reqres.in/api/users
Accept: application/json
Content-Language: de-DE

头部信息必须紧随 url 后面,中间可以有空行或注释(# 注释)。

有些字段有自己的默认值

1
2
3
4
5
6
7
MIME-Version: 1.0
Connection: close or keep-alive
Content-Length: number of bytes in request body (only when body is present)
Host: URL host
Accept: */* (default value, but may be overwritten by the user)
Accept-Encoding: gzip
Extension: Security/Digest Security/SSL

例子:

1
2
3
4
5
6
7
8
post https://reqres.in/api/users
Accept: application/json
Content-Type: application/json; charset=utf-8

{
    "name": "John",
    "age": 42
}
1
(Request timed out after 10.03 seconds)

另外请求的数据体还可以用

1
2
3
4
{
  "name": "John",
  "age": 42
}

形式表示。

Verb Variables   verb

template https://reqres.in/api/users Accept: application/json Authentication: {{(verb-var token)}}

{{(verb-var token)}}

这等于是执行的时候要求你输入一个 token 值,如果想设置默认的值就这样:

{{(verb-var token "default value")}}

Get users list

get Content-Language: de-DE

Create a user

post Content-Type: application/json; charset=utf-8

{ "name": "{{(user-full-name)}}", "age": "{{(read-string "Age: ")}}" }

Org Header Properties   verb

:properties: :test: 这是个标题属性 🔚

除了 Verb-Store 之外的其它以 Verb- 开始的都会被当作 metadata 添加到请求中去。

Verb-Map-Request

:properties: :Verb-Map-Request: remove-body-newlines 🔚

post /{{(verb-var user-id)}}/upload Content-Type: text/plain; charset=utf-8

foo, bar, baz

如上面的数据在发送之前会被 remove-body-newlines 处理之后返回,即实际发送给服务 器的变成了: foo,bar,baz

1
2
3
4
(defun remove-body-newlines (rs)
  ;; RS is of type `verb-request-spec'
  (oset rs body (replace-regexp-in-string "\n" " " (oref rs body)))
  rs)

可以通过给 org head 增加 Verb-Map-Request 来指定一个函数,这个函数会在请求发出 或导出之前执行。

Verb-Store   verb

template https://reqres.in/api Accept: application/json Content-Type: application/json; charset=utf-8

这个属性很特殊,当指定了这个之后,请求的结果会自动保存到这它指定的变量上去。

然后可以通过 verb-stored-response 函数去取到这个变量的值。

如:

Create a user

:properties: :Verb-Store: new-user 🔚

post Content-Type: application/json; charset=utf-8

{ "name": "{{(user-full-name)}}", "age": "{{(read-string "Age: ")}}" }

这里的结果保存到了 new-user

Get last created user

get /{{(verb-json-get (oref (verb-stored-response "new-user") body) "id")}} Accept: application/json

这里去取保存的结果。

Get IP

:properties: :Verb-Store: new-person 🔚

post /users

{ "name": "John", "age": 42 }

get Stored IP

get /users/{{(verb-json-get (oref (verb-stored-response "new-person") body) "id")}}

Get Last Response

get /users/{{(verb-json-get (oref verb-last body) "id")}}

取上一个请求的响应数据。

Org Source Block Properties

:wrap

:wrap src ob-verb-response

指定结果用 src block 将结果包起来。

1
get https://api.ipify.org?format=json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
HTTP/1.1 200 OK
Server: Cowboy
Connection: keep-alive
Content-Type: application/json
Vary: Origin
Date: Sat, 24 Jul 2021 11:15:56 GMT
Content-Length: 22
Via: 1.1 vegur

{
  "ip": "27.38.254.246"
}

:op

没有指定 :op 的时候默认是 :op send

TIP

可以使用 :var keyword 来给 verb src block 传递参数,然后在代码块中用

(verb-var <variable-name>) 使用。

  1. :op send get-headers: 只显示响应头信息。

    1
    
     get https://api.ipify.org?format=json
    1
    2
    3
    4
    5
    6
    7
    
    Server: Cowboy
    Connection: keep-alive
    Content-Type: application/json
    Vary: Origin
    Date: Sat, 24 Jul 2021 11:11:31 GMT
    Content-Length: 22
    Via: 1.1 vegur
  2. :op send get-body: 只显示响应体信息。

    1
    
     get https://api.ipify.org?format=json
    1
    2
    3
    
    {
      "ip": "27.38.254.246"
    }
  3. :op export curl 将请求导出为 CURL 格式。

    1
    
     get https://api.ipify.org?format=json
    curl 'https://api.ipify.org/?format=json'
    
  4. :op export verb 将请求导出为 verb 格式。

    1
    
     get https://api.ipify.org?format=json
    GET https://api.ipify.org/?format=json
    

Upload File

1
2
3
4
post /{{(verb-var user-id)}}/upload
Content-Type: text/markdown; charset=utf-8

{{(verb-read-file "~/Desktop/test.md")}}

下面为什么内容前面要加上 {{}} ,因为 org-mode 默认 ** 是标题,加个空的 {{}} 可避免问题。

1
2
3
4
5
6
7
post /{{(verb-var user-id)}}/upload
Content-Type: text/markdown; charset=utf-8

# Sample Markdown file

{{}}**This text is bold.**
{{}}*This text is italicized.*

Upload Multiple Files

post www.example.com Accept: / Content-Type: multipart/form-data; boundary={{(verb-boundary)}}

{{(verb-part "file" "1.txt")}} Content-Type: text/plain

{{(verb-read-file "/path/to/1.txt")}} {{(verb-part "file" "2.html")}} Content-Type: text/html

{{(verb-read-file "/path/to/2.html")}} {{(verb-part)}}

Binary content type tests   verb

template https://www.gnu.org

PDF

get /licenses/quick-guide-gplv3.pdf

Images

template /graphics

PNG image

get /gnu-head.png

JPG image

get /bokma-gnu.jpg

SVG image

get /logo-fsf.org.svg

/dev/null as a Service   verb

post https://devnull-as-a-service.com/dev/null Content-Type: text/plain; charset=utf-8

Hello!

Hacker News API   verb

template https://hacker-news.firebaseio.com/v0 Accept: application/json

Item

get /item/{{(read-string "Item ID: ")}}.json?print=pretty

User

get /user/{{(read-string "User ID: ")}}.json

Live Data

Max Item ID

get /maxitem.json

Top Stories

get /topstories.json

New Stories

get /newstories.json

Best Stories

get /beststories.json

Export to EWW example   verb

get http://neverssl.com Accept: text/html

ipify API   verb

IPv4

template https://api.ipify.org

JSON

get ?format=json

Text

get ?format=text

IPv6

template https://api6.ipify.org

JSON

get ?format=json

Text

get ?format=text

Kanye REST API   verb

template https://api.kanye.rest

Get quotes text response (Babel)

:properties: :Verb-Store: kanye 🔚

1
get ?format=text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
HTTP/1.1 200 OK
Date: Sat, 24 Jul 2021 05:29:44 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: GET
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=yHwX2nlypygqT90DSvEtAsrxWQU9YjDmSajgfG9hzsmYqNFvKAAZRP0CqOKVhvgSZ4b1cdLk1d%2BF8gxrow4rkKyy1xnIxtB9qUv4XfU2Ls6GETgSh7uthXVNf5T6oz3V2g%3D%3D"}],"group":"cf-nel","max_age":604800}
NEL: {"report_to":"cf-nel","max_age":604800}
Vary: Accept-Encoding
Server: cloudflare
CF-RAY: 673ac0a53ce6eb3d-LAX
alt-svc: h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400, h3=":443"; ma=86400

{
  "quote": "I don't wanna see no woke tweets or hear no woke raps ... it's show time ... it's a whole different energy right now"
}

Get JSON quotes, body only (Babel)

1
get
1
2
3
{
  "quote": "The thought police want to suppress freedom of thought"
}

Get JSON quotes

1
get
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
HTTP/1.1 200 OK
Date: Sun, 25 Jul 2021 06:37:39 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: GET
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=b%2Bwjrw%2BO3AfKcLJXXQYyedGb%2BGEF%2BOrodpiucCNhs2kiJRw4kI6axDCBz6uIXKsMajdiiL2FLSy34eVmH0HyBQ22Vt6zK91I4aeHHXQ2bJYC4OQs6tj34Cc3x4Y93xOplg%3D%3D"}],"group":"cf-nel","max_age":604800}
NEL: {"report_to":"cf-nel","max_age":604800}
Vary: Accept-Encoding
Server: cloudflare
CF-RAY: 67436180ffac3131-LAX
alt-svc: h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400, h3=":443"; ma=86400

{
  "quote": "If I got any cooler I would freeze to death"
}

Open Library API   verb

template http://openlibrary.org User-Agent: Verb/Emacs Emacs/{{emacs-version}} Accept: application/json

Search

template /search.json

By Title
1
get ?title={{(verb-var title)}}
By Author

get ?author={{(verb-var author "Frank Herbert")}}

Subjects

get /subjects/{{(verb-var subject)}}.json

Books

:properties: :Verb-Store: book 🔚

get /api/books?bibkeys=ISBN:{{(verb-var isbn)}}&format=json

Book Cover

get {{(verb-json-get (oref (verb-stored-response "book") body) (concat "ISBN:" (verb-var isbn)) "thumbnail_url")}} Accept: image/jpeg

Postman Echo API   verb

template https://postman-echo.com

GZIP test

get /gzip Accept-Encoding: gzip

Stream test

get /stream/5

Post

post /post Content-Type: application/json

{ "hello": 1, "bye": {} }

Post (raw text)

template Content-Type: text/plain

{{(verb-read-file "../test/test.txt")}}

Status code

get /status/{{(read-number "Status: ")}}

REQ|RES   verb

template https://reqres.in/api?delay=0 Content-Type: application/json

Users

template /users

Get endpoint headers

head

Get endpoint options

options

List users

get ?page=1

Create user

post Content-Type: application/json

{ "name": "{{(user-login-name)}}", "age": 55 }

Operate on a single user

template /2

Get a single user

get

Replace a user

put

{ "name": "Bob" }

Update a user

patch

{ "name": "Bob" }

Delete a user

delete

Login

post /login

1
2
3
4
{
    "email": "eve.holt@reqres.in",
    "password": "hello"
}

Scryfall REST API   verb

template https://api.scryfall.com

Cards list

get /cards

Single card by ID

get /{{(read-string "Card ID: " "4b332e3d-dcf4-4f62-8130-124ec5d23b90")}}?format=text

Get a random card image

get /random?format=image

Sets

get /sets

Single set by ID

get /{{(read-string "Set ID: " "914a6c6d-cb3b-45e8-a2db-9978a2339faf")}}

API2 convert   verb

template https://api2.online-convert.com x-oc-api-key: d89c39a23d8f41ca8fd13ef85297b9a7 Cache-Control: no-cache

api documents

get id and server

:properties: :Verb-Store: convert-response 🔚

post /jobs

{ "conversion": [{ "category": "image", "target": "png" }] }

base64 -> image

:properties: :Verb-Store: image-response 🔚

POST {{(verb-json-get (oref (verb-stored-response "convert-response") body) "server")}}/upload-base64/{{(verb-json-get (oref (verb-stored-response "convert-response") body) "id")}} Content-Type: image/png

{ "content": "data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=", "filename": "black-pixel" }

get the upload image

POST /jobs

{ "input": [{ "type": "input_id", "source": "{{(verb-json-get (oref (verb-stored-response "image-response") body) "id" "input")}}" }], "conversion": [{ "target": "png" }] }

multiple image

POST /dl/web2/upload-base64/a6f691e2-839e-49e5-829d-dc2d97486fe1 Content-Type: application/json

[{ "content": "data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=", "filename": "black_pixel.gif" },{ "content": "data:text/plain;base64,dGVzdCBzdHJpbmc=", "filename": "example_string.txt" }]

tables

列宽和对齐(Column width and alignment)

1onesome
2twoboring
3this is a long textcolumn

keybindings

逗号(,)

, s trees/subtrees 操作

keyfunctiondescription
, s horg-premote-subtree升级, h4 -> h3
, s lorg-demote-subtree降级, h3 -> h4
, s norg-narrow-to-subtree定位到当前的标题试图,隐藏其他
, s Nwiden恢复隐藏
, s jorg-move-subtree-down当前树下移
, s korg-move-subtree-up当前树上移

, b org-babel-* 操作

keyfunctiondescription
, b porg-babel-previous-src-block跳转到上一个代码块
, b norg-babel-next-src-block跳转到下一个代码块

Hyperlinks(超链接)

Internal Links(内部链接)

  1. org file link target: <<target>> link source: target

    这种方式在 hugo 中无法时候用,但是可以通过第二种方式的 PROP: CUSTOM_ID 来实现。

  2. in hugo link target: doc_header 必须在某个标题下面声明属性,才能其效果。

      :PROPERTIES:
      :COLUMNS: %CUSTOM_ID[(Custom Id)]
      :CUSTOM_ID: doc_header
      :END:
    

    link source: C-c C-l 或者 org-insert-link 或者直接 [[#doc_header][文档开 头位置]] ,请点击:文档开头位置

实现非标题项内部跳转

添加 meta: @@html:<span id="test-link"></span>

添加链接跳转到上面的 meta: @@html:<a href="#test-link">some thing</a>

这样点击 some thing 会占满到 id 为 test-link 的那个元素位置。

如: 请点击下面的链接跳回到我这里来。。。。

some thing !!!

some thing !!!

some thing !!!

some thing !!!

some thing !!!

some thing !!!

some thing !!!

some thing !!!

some thing !!!

some thing !!!

some thing !!!

some thing !!!

some thing !!!

🔗点我跳回到上面!!

Markup for Rich Contents(富文本)

Literal Examples(文本模板)

适合长文本内容的:

* some example from a text file

如果只是简短的语句,可直接使用 `:`(冒号)也可以达到同样效果:

* some short example from a text file

代码模板:

1
2
3
  (defun org-xor (a b) (ref:sc)
         "Exclusive or."    (ref:jump)
         (if a (not b) b))

配置选项: -n ,可以在代码中加入引用 (ref:sc) ,然后在文章任意地方使用 [[(sc)]] 创建一个链接,点击后可以定位到代码中该出。

In line (sc) we remember the current position. Line (jump) jumps to point-min.

link: literal_eg

16 Miscellaneous(杂项)

16.2 Structure Templates(结构化模板)

  a	‘#+BEGIN_EXPORT ascii’ … ‘#+END_EXPORT’
  c	‘#+BEGIN_CENTER’ … ‘#+END_CENTER’
  C	‘#+BEGIN_COMMENT’ … ‘#+END_COMMENT’
  e	‘#+BEGIN_EXAMPLE’ … ‘#+END_EXAMPLE’
  E	‘#+BEGIN_EXPORT’ … ‘#+END_EXPORT’
  h	‘#+BEGIN_EXPORT html’ … ‘#+END_EXPORT’
  l	‘#+BEGIN_EXPORT latex’ … ‘#+END_EXPORT’
  q	‘#+BEGIN_QUOTE’ … ‘#+END_QUOTE’
  s	‘#+BEGIN_SRC’ … ‘#+END_SRC’
  v	‘#+BEGIN_VERSE’ … ‘#+END_VERSE’

16.7 Summary of In-Buffer Settings(文件设置)

  1. `#+STARTUP:`

    optionfunction
    indent开启自动缩进
    noindent关闭西东缩进

Org-mode in hugo

给图片增加属性(使用 #+attr_html):

#+attr_html: :width 100 :height 200
[[/images/some-img.png]]

#+ 开头的属性

  • #+caption: 设置表名称

  • #+attr_html 增加 html 属性,比如:

    1. 增加样式名: #+attr_html: :class classname

    2. 设置宽高: #+attr_html: :width 100 :height 100

  • #+attr_css 增加 css 样式,比如:

    1. 设置宽高: #+attr_css: :width 100px :height 200px :text-align center ,注意和 html 属性区 分开

snippets

首字母大写

新增函数:

1
2
3
4
5
6
(defun my/capitalize-first-char (&optional string)
  "Capitalize only the first character of the input STRING."
  (when (and string (> (length string) 0))
    (let ((first-char (substring string nil 1))
          (rest-str   (substring string 1)))
      (concat (capitalize first-char) rest-str))))

然后在 snippet 文件中调用:

# -*- mode: snippet -*-
# name: intro
# key: zname
# --
Hi, my name is ${1:$$(my/capitalize-first-char yas-text)}.
$0