diff --git a/.gitignore b/.gitignore index e3ffc41..bc951af 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ node_modules .vscode-test/ *.vsix */**/__pycache__/* -dist +dist \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ef114a..beca69f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,4 +52,10 @@ All notable changes to the "rmarkdown" extension will be documented in this file ### Added -- 'Bookdown: Serve Book' command \ No newline at end of file +- 'Bookdown: Serve Book' command + +## 0.0.9 - 2020-04-17 + +### Added + +- Table formatter \ No newline at end of file diff --git a/README.md b/README.md index d31f86a..bc5238d 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ Additionally, it aims to provide some helper functions for Bookdown and Blogdown - [Serve Site](#serve-site) - [Other Markdown Features](#other-markdown-features) - [Syntax Highlighting](#syntax-highlighting) + - [Table Formatter](#table-formatter) - [Keyboard Shortcuts](#keyboard-shortcuts-1) - [TODO](#todo) - [Change Log](#change-log) @@ -116,6 +117,10 @@ Before you can use blogdown-specific features, you need to first open the direct Mostly adapted from [microsoft/vscode](https://github.com/microsoft/vscode/tree/master/extensions/markdown-language-features) and [yzhang-gh/vscode-markdown](https://github.com/yzhang-gh/vscode-markdown). +## Table Formatter + +![table formatter demo](./images/demo/table-format.gif) + ## Keyboard Shortcuts Mostly adapted from [yzhang-gh/vscode-markdown](https://github.com/yzhang-gh/vscode-markdown). diff --git a/a.json b/a.json new file mode 100644 index 0000000..fe88898 --- /dev/null +++ b/a.json @@ -0,0 +1,1471 @@ +{ + "blocks": [ + { "t": "Header", "c": [1, ["r-markdown-all-in-one-for-vs-code", [], []], [{ "t": "Str", "c": "R" }, { "t": "Space" }, { "t": "Str", "c": "Markdown" }, { "t": "Space" }, { "t": "Str", "c": "All-in-One" }, { "t": "Space" }, { "t": "Str", "c": "for" }, { "t": "Space" }, { "t": "Str", "c": "VS" }, { "t": "Space" }, { "t": "Str", "c": "Code" }]] }, + { + "t": "Para", + "c": [ + { "t": "Str", "c": "This" }, + { "t": "Space" }, + { "t": "Str", "c": "extension" }, + { "t": "Space" }, + { "t": "Str", "c": "provides" }, + { "t": "Space" }, + { "t": "Str", "c": "a" }, + { "t": "Space" }, + { "t": "Str", "c": "few" }, + { "t": "Space" }, + { "t": "Str", "c": "snippets" }, + { "t": "Space" }, + { "t": "Str", "c": "and" }, + { "t": "Space" }, + { "t": "Str", "c": "key" }, + { "t": "Space" }, + { "t": "Str", "c": "bindings" }, + { "t": "Space" }, + { "t": "Str", "c": "for" }, + { "t": "Space" }, + { "t": "Str", "c": "common" }, + { "t": "Space" }, + { "t": "Str", "c": "tasks" }, + { "t": "Space" }, + { "t": "Str", "c": "in" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], ".Rmd"] }, + { "t": "Space" }, + { "t": "Str", "c": "documents," }, + { "t": "Space" }, + { "t": "Str", "c": "such" }, + { "t": "Space" }, + { "t": "Str", "c": "as" }, + { "t": "Space" }, + { "t": "Str", "c": "inserting" }, + { "t": "Space" }, + { "t": "Str", "c": "code" }, + { "t": "Space" }, + { "t": "Str", "c": "chunks" }, + { "t": "Space" }, + { "t": "Str", "c": "and" }, + { "t": "Space" }, + { "t": "Str", "c": "including" }, + { "t": "Space" }, + { "t": "Str", "c": "images" }, + { "t": "Space" }, + { "t": "Str", "c": "using" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "knitr::include_graphics()"] }, + { "t": "Str", "c": "." } + ] + }, + { + "t": "Para", + "c": [ + { "t": "Str", "c": "Additionally," }, + { "t": "Space" }, + { "t": "Str", "c": "it" }, + { "t": "Space" }, + { "t": "Str", "c": "aims" }, + { "t": "Space" }, + { "t": "Str", "c": "to" }, + { "t": "Space" }, + { "t": "Str", "c": "provide" }, + { "t": "Space" }, + { "t": "Str", "c": "some" }, + { "t": "Space" }, + { "t": "Str", "c": "helper" }, + { "t": "Space" }, + { "t": "Str", "c": "functions" }, + { "t": "Space" }, + { "t": "Str", "c": "for" }, + { "t": "Space" }, + { "t": "Str", "c": "Bookdown" }, + { "t": "Space" }, + { "t": "Str", "c": "and" }, + { "t": "Space" }, + { "t": "Str", "c": "Blogdown." } + ] + }, + { "t": "Header", "c": [1, ["table-of-contents", [], []], [{ "t": "Str", "c": "Table" }, { "t": "Space" }, { "t": "Str", "c": "of" }, { "t": "Space" }, { "t": "Str", "c": "Contents" }]] }, + { + "t": "BulletList", + "c": [ + [ + { + "t": "Plain", + "c": [ + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "R" }, { "t": "Space" }, { "t": "Str", "c": "Markdown" }, { "t": "Space" }, { "t": "Str", "c": "All-in-One" }, { "t": "Space" }, { "t": "Str", "c": "for" }, { "t": "Space" }, { "t": "Str", "c": "VS" }, { "t": "Space" }, { "t": "Str", "c": "Code" }], + ["#r-markdown-all-in-one-for-vs-code", ""] + ] + } + ] + } + ], + [ + { + "t": "Plain", + "c": [ + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "Table" }, { "t": "Space" }, { "t": "Str", "c": "of" }, { "t": "Space" }, { "t": "Str", "c": "Contents" }], + ["#table-of-contents", ""] + ] + } + ] + } + ], + [ + { + "t": "Plain", + "c": [ + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "Video" }, { "t": "Space" }, { "t": "Str", "c": "Demos" }], + ["#video-demos", ""] + ] + } + ] + }, + { + "t": "BulletList", + "c": [ + [ + { + "t": "Plain", + "c": [ + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "Code" }, { "t": "Space" }, { "t": "Str", "c": "Chunk" }], + ["#code-chunk", ""] + ] + } + ] + } + ], + [ + { + "t": "Plain", + "c": [ + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "Include" }, { "t": "Space" }, { "t": "Str", "c": "Graphics" }], + ["#include-graphics", ""] + ] + } + ] + } + ], + [{ "t": "Plain", "c": [{ "t": "Link", "c": [["", [], []], [{ "t": "Str", "c": "Knitting" }], ["#knitting", ""]] }] }] + ] + } + ], + [ + { + "t": "Plain", + "c": [ + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "RMarkdown-Specific" }, { "t": "Space" }, { "t": "Str", "c": "Features" }], + ["#rmarkdown-specific-features", ""] + ] + } + ] + }, + { + "t": "BulletList", + "c": [ + [ + { + "t": "Plain", + "c": [ + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "Keyboard" }, { "t": "Space" }, { "t": "Str", "c": "Shortcuts:" }], + ["#keyboard-shortcuts", ""] + ] + } + ] + } + ], + [ + { "t": "Plain", "c": [{ "t": "Link", "c": [["", [], []], [{ "t": "Str", "c": "Snippets" }], ["#snippets", ""]] }] }, + { "t": "BulletList", "c": [[{ "t": "Plain", "c": [{ "t": "Link", "c": [["", [], []], [{ "t": "Str", "c": "Cross-referencing" }], ["#cross-referencing", ""]] }] }], [{ "t": "Plain", "c": [{ "t": "Link", "c": [["", [], []], [{ "t": "Str", "c": "Chunks" }], ["#chunks", ""]] }] }]] } + ] + ] + } + ], + [ + { + "t": "Plain", + "c": [ + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "Bookdown-Specific" }, { "t": "Space" }, { "t": "Str", "c": "Features" }], + ["#bookdown-specific-features", ""] + ] + } + ] + }, + { + "t": "BulletList", + "c": [ + [ + { + "t": "Plain", + "c": [ + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "Serve" }, { "t": "Space" }, { "t": "Str", "c": "Book" }], + ["#serve-book", ""] + ] + } + ] + } + ] + ] + } + ], + [ + { + "t": "Plain", + "c": [ + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "Blogdown-Specific" }, { "t": "Space" }, { "t": "Str", "c": "Features" }], + ["#blogdown-specific-features", ""] + ] + } + ] + }, + { + "t": "BulletList", + "c": [ + [ + { + "t": "Plain", + "c": [ + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "New" }, { "t": "Space" }, { "t": "Str", "c": "Post" }], + ["#new-post", ""] + ] + } + ] + } + ], + [ + { + "t": "Plain", + "c": [ + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "Serve" }, { "t": "Space" }, { "t": "Str", "c": "Site" }], + ["#serve-site", ""] + ] + } + ] + } + ] + ] + } + ], + [ + { + "t": "Plain", + "c": [ + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "Other" }, { "t": "Space" }, { "t": "Str", "c": "Markdown" }, { "t": "Space" }, { "t": "Str", "c": "Features" }], + ["#other-markdown-features", ""] + ] + } + ] + }, + { + "t": "BulletList", + "c": [ + [ + { + "t": "Plain", + "c": [ + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "Syntax" }, { "t": "Space" }, { "t": "Str", "c": "Highlighting" }], + ["#syntax-highlighting", ""] + ] + } + ] + } + ], + [ + { + "t": "Plain", + "c": [ + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "Keyboard" }, { "t": "Space" }, { "t": "Str", "c": "Shortcuts" }], + ["#keyboard-shortcuts-1", ""] + ] + } + ] + } + ] + ] + } + ], + [{ "t": "Plain", "c": [{ "t": "Link", "c": [["", [], []], [{ "t": "Str", "c": "TODO" }], ["#todo", ""]] }] }], + [ + { + "t": "Plain", + "c": [ + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "Change" }, { "t": "Space" }, { "t": "Str", "c": "Log" }], + ["#change-log", ""] + ] + } + ] + } + ] + ] + }, + { "t": "Header", "c": [1, ["video-demos", [], []], [{ "t": "Str", "c": "Video" }, { "t": "Space" }, { "t": "Str", "c": "Demos" }]] }, + { + "t": "Para", + "c": [ + { + "t": "Emph", + "c": [ + { "t": "Str", "c": "If" }, + { "t": "Space" }, + { "t": "Str", "c": "you" }, + { "t": "Space" }, + { "t": "Str", "c": "prefer" }, + { "t": "Space" }, + { "t": "Str", "c": "reading" }, + { "t": "Space" }, + { "t": "Str", "c": "text," }, + { "t": "Space" }, + { "t": "Str", "c": "jump" }, + { "t": "Space" }, + { "t": "Str", "c": "to" }, + { "t": "Space" }, + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "RMarkdown-Specific" }, { "t": "Space" }, { "t": "Str", "c": "Features" }], + ["#user-content-rmarkdown-specific-features", ""] + ] + }, + { "t": "Str", "c": "," }, + { "t": "Space" }, + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "Blogdown-Specific" }, { "t": "Space" }, { "t": "Str", "c": "Features" }], + ["#blogdown-specific-features", ""] + ] + }, + { "t": "Str", "c": "," }, + { "t": "Space" }, + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "Bookdown-Specific" }, { "t": "Space" }, { "t": "Str", "c": "Features" }], + ["#bookdown-specific-features", ""] + ] + }, + { "t": "Str", "c": "," }, + { "t": "Space" }, + { "t": "Str", "c": "or" }, + { "t": "Space" }, + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "Other" }, { "t": "Space" }, { "t": "Str", "c": "Markdown" }, { "t": "Space" }, { "t": "Str", "c": "Features" }], + ["#other-markdown-features", ""] + ] + }, + { "t": "Str", "c": "." } + ] + } + ] + }, + { "t": "Header", "c": [2, ["code-chunk", [], []], [{ "t": "Str", "c": "Code" }, { "t": "Space" }, { "t": "Str", "c": "Chunk" }]] }, + { + "t": "Para", + "c": [ + { "t": "Str", "c": "As" }, + { "t": "Space" }, + { "t": "Str", "c": "you" }, + { "t": "Space" }, + { "t": "Str", "c": "would" }, + { "t": "Space" }, + { "t": "Str", "c": "do" }, + { "t": "Space" }, + { "t": "Str", "c": "in" }, + { "t": "Space" }, + { "t": "Str", "c": "RStudio," }, + { "t": "Space" }, + { "t": "Str", "c": "you" }, + { "t": "Space" }, + { "t": "Str", "c": "can" }, + { "t": "Space" }, + { "t": "Str", "c": "use" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "Ctrl/Cmd+Alt+I"] }, + { "t": "Space" }, + { "t": "Str", "c": "to" }, + { "t": "Space" }, + { "t": "Str", "c": "insert" }, + { "t": "Space" }, + { "t": "Str", "c": "a" }, + { "t": "Space" }, + { "t": "Str", "c": "code" }, + { "t": "Space" }, + { "t": "Str", "c": "chunk" }, + { "t": "Space" }, + { "t": "Str", "c": "(alternatively," }, + { "t": "Space" }, + { "t": "Str", "c": "you" }, + { "t": "Space" }, + { "t": "Str", "c": "can" }, + { "t": "Space" }, + { "t": "Str", "c": "write" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "\\code"] }, + { "t": "Space" }, + { "t": "Str", "c": "to" }, + { "t": "Space" }, + { "t": "Str", "c": "trigger" }, + { "t": "Space" }, + { "t": "Str", "c": "this" }, + { "t": "Space" }, + { "t": "Str", "c": "snippet)." }, + { "t": "Space" }, + { "t": "Str", "c": "The" }, + { "t": "Space" }, + { "t": "Str", "c": "language" }, + { "t": "Space" }, + { "t": "Str", "c": "defaults" }, + { "t": "Space" }, + { "t": "Str", "c": "to" }, + { "t": "Space" }, + { "t": "Str", "c": "R," }, + { "t": "Space" }, + { "t": "Str", "c": "but" }, + { "t": "Space" }, + { "t": "Str", "c": "you" }, + { "t": "Space" }, + { "t": "Str", "c": "can" }, + { "t": "Space" }, + { "t": "Str", "c": "also" }, + { "t": "Space" }, + { "t": "Str", "c": "use" }, + { "t": "Space" }, + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "many" }, { "t": "Space" }, { "t": "Str", "c": "other" }, { "t": "Space" }, { "t": "Str", "c": "langauges" }], + ["https://bookdown.org/yihui/rmarkdown/language-engines.html", ""] + ] + }, + { "t": "Space" }, + { "t": "Str", "c": "supported" }, + { "t": "Space" }, + { "t": "Str", "c": "by" }, + { "t": "Space" }, + { "t": "Link", "c": [["", [], []], [{ "t": "Strong", "c": [{ "t": "Str", "c": "knitr" }] }], ["https://yihui.org/knitr/", ""]] }, + { "t": "Str", "c": "." } + ] + }, + { + "t": "Para", + "c": [ + { + "t": "Image", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "insert" }, { "t": "Space" }, { "t": "Str", "c": "code" }, { "t": "Space" }, { "t": "Str", "c": "chunk" }, { "t": "Space" }, { "t": "Str", "c": "demo" }], + ["./images/demo/code.gif", "fig:"] + ] + } + ] + }, + { + "t": "Para", + "c": [ + { "t": "Str", "c": "The" }, + { "t": "Space" }, + { "t": "Str", "c": "first" }, + { "t": "Space" }, + { "t": "Str", "c": "tab" }, + { "t": "Space" }, + { "t": "Str", "c": "stop" }, + { "t": "Space" }, + { "t": "Str", "c": "allows" }, + { "t": "Space" }, + { "t": "Str", "c": "you" }, + { "t": "Space" }, + { "t": "Str", "c": "to" }, + { "t": "Space" }, + { "t": "Str", "c": "configure" }, + { "t": "Space" }, + { "t": "Str", "c": "this" }, + { "t": "Space" }, + { "t": "Str", "c": "code" }, + { "t": "Space" }, + { "t": "Str", "c": "chunk" }, + { "t": "Space" }, + { "t": "Str", "c": "(language," }, + { "t": "Space" }, + { "t": "Str", "c": "label," }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "eval"] }, + { "t": "Str", "c": "," }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "echo"] }, + { "t": "Str", "c": "," }, + { "t": "Space" }, + { "t": "Str", "c": "etc.)," }, + { "t": "Space" }, + { "t": "Str", "c": "and" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "second" }, + { "t": "Space" }, + { "t": "Str", "c": "one" }, + { "t": "Space" }, + { "t": "Str", "c": "is" }, + { "t": "Space" }, + { "t": "Str", "c": "where" }, + { "t": "Space" }, + { "t": "Str", "c": "you" }, + { "t": "Space" }, + { "t": "Str", "c": "write" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "code." }, + { "t": "Space" }, + { "t": "Str", "c": "The" }, + { "t": "Space" }, + { "t": "Str", "c": "third" }, + { "t": "Space" }, + { "t": "Str", "c": "tab" }, + { "t": "Space" }, + { "t": "Str", "c": "stop" }, + { "t": "Space" }, + { "t": "Str", "c": "inserts" }, + { "t": "Space" }, + { "t": "Str", "c": "a" }, + { "t": "Space" }, + { "t": "Str", "c": "blank" }, + { "t": "Space" }, + { "t": "Str", "c": "line" }, + { "t": "Space" }, + { "t": "Str", "c": "between" }, + { "t": "Space" }, + { "t": "Str", "c": "after" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "code" }, + { "t": "Space" }, + { "t": "Str", "c": "chunk," }, + { "t": "Space" }, + { "t": "Str", "c": "which" }, + { "t": "Space" }, + { "t": "Str", "c": "is" }, + { "t": "Space" }, + { "t": "Str", "c": "required" }, + { "t": "Space" }, + { "t": "Str", "c": "by" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], ".Rmd"] }, + { "t": "Space" }, + { "t": "Str", "c": "format." } + ] + }, + { "t": "Header", "c": [2, ["include-graphics", [], []], [{ "t": "Str", "c": "Include" }, { "t": "Space" }, { "t": "Str", "c": "Graphics" }]] }, + { + "t": "Para", + "c": [ + { "t": "Str", "c": "In" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "world" }, + { "t": "Space" }, + { "t": "Str", "c": "of" }, + { "t": "Space" }, + { "t": "Str", "c": "R" }, + { "t": "Space" }, + { "t": "Str", "c": "Markdown," }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "knitr::include_graphics()"] }, + { "t": "Space" }, + { "t": "Str", "c": "is" }, + { "t": "Space" }, + { + "t": "Link", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "the" }, { "t": "Space" }, { "t": "Str", "c": "preferred" }, { "t": "Space" }, { "t": "Str", "c": "way" }, { "t": "Space" }, { "t": "Str", "c": "of" }, { "t": "Space" }, { "t": "Str", "c": "inserting" }, { "t": "Space" }, { "t": "Str", "c": "images" }, { "t": "Space" }, { "t": "Str", "c": "over" }], + ["http://zevross.com/blog/2017/06/19/tips-and-tricks-for-working-with-images-and-figures-in-r-markdown-documents/#more-functionality-from-include_graphics", ""] + ] + }, + { "t": "Space" }, + { "t": "Str", "c": "Markdown’s" }, + { "t": "Space" }, + { "t": "Str", "c": "native" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "![]()"] }, + { "t": "Space" }, + { "t": "Str", "c": "syntax." }, + { "t": "Space" }, + { "t": "Str", "c": "If" }, + { "t": "Space" }, + { "t": "Str", "c": "you" }, + { "t": "Space" }, + { "t": "Str", "c": "don’t" }, + { "t": "Space" }, + { "t": "Str", "c": "know" }, + { "t": "Space" }, + { "t": "Str", "c": "it," }, + { "t": "Space" }, + { "t": "Str", "c": "you" }, + { "t": "Space" }, + { "t": "Str", "c": "should." }, + { "t": "Space" }, + { "t": "Str", "c": "Its" }, + { "t": "Space" }, + { "t": "Str", "c": "syntax," }, + { "t": "Space" }, + { "t": "Str", "c": "however," }, + { "t": "Space" }, + { "t": "Str", "c": "is" }, + { "t": "Space" }, + { "t": "Str", "c": "rather" }, + { "t": "Space" }, + { "t": "Str", "c": "verbose." } + ] + }, + { + "t": "Para", + "c": [ + { "t": "Str", "c": "With" }, + { "t": "Space" }, + { "t": "Str", "c": "VSCode" }, + { "t": "Space" }, + { "t": "Str", "c": "RMarkdown" }, + { "t": "Space" }, + { "t": "Str", "c": "extension," }, + { "t": "Space" }, + { "t": "Str", "c": "you" }, + { "t": "Space" }, + { "t": "Str", "c": "use" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "\\fig"] }, + { "t": "Space" }, + { "t": "Str", "c": "snippet." } + ] + }, + { + "t": "Para", + "c": [ + { + "t": "Image", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "include" }, { "t": "Space" }, { "t": "Str", "c": "graphics" }, { "t": "Space" }, { "t": "Str", "c": "demo" }], + ["./images/demo/fig.gif", "fig:"] + ] + } + ] + }, + { "t": "Header", "c": [2, ["knitting", [], []], [{ "t": "Str", "c": "Knitting" }]] }, + { + "t": "Para", + "c": [ + { "t": "Str", "c": "Use" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "Ctrl/Cmd+Shift+K"] }, + { "t": "Space" }, + { "t": "Str", "c": "to" }, + { "t": "Space" }, + { "t": "Str", "c": "knit" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "document" }, + { "t": "Space" }, + { "t": "Str", "c": "with" }, + { "t": "Space" }, + { "t": "Str", "c": "options" }, + { "t": "Space" }, + { "t": "Str", "c": "specified" }, + { "t": "Space" }, + { "t": "Str", "c": "in" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "YAML" }, + { "t": "Space" }, + { "t": "Str", "c": "header," }, + { "t": "Space" }, + { "t": "Str", "c": "like" }, + { "t": "Space" }, + { "t": "Str", "c": "in" }, + { "t": "Space" }, + { "t": "Str", "c": "RStudio." } + ] + }, + { + "t": "Para", + "c": [ + { + "t": "Image", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "knitting" }, { "t": "Space" }, { "t": "Str", "c": "demo" }], + ["./images/demo/knit.gif", "fig:"] + ] + } + ] + }, + { "t": "Header", "c": [1, ["rmarkdown-specific-features", [], []], [{ "t": "Str", "c": "RMarkdown-Specific" }, { "t": "Space" }, { "t": "Str", "c": "Features" }]] }, + { "t": "Header", "c": [2, ["keyboard-shortcuts", [], []], [{ "t": "Str", "c": "Keyboard" }, { "t": "Space" }, { "t": "Str", "c": "Shortcuts:" }]] }, + { + "t": "Table", + "c": [ + [], + [{ "t": "AlignCenter" }, { "t": "AlignCenter" }, { "t": "AlignCenter" }, { "t": "AlignCenter" }], + [0.136, 0.112, 0.112, 0.64], + [[{ "t": "Plain", "c": [{ "t": "Str", "c": "Description" }] }], [{ "t": "Plain", "c": [{ "t": "Str", "c": "Windows/Linux" }] }], [{ "t": "Plain", "c": [{ "t": "Str", "c": "Mac" }] }], [{ "t": "Plain", "c": [{ "t": "Str", "c": "Note" }] }]], + [ + [ + [{ "t": "Plain", "c": [{ "t": "Str", "c": "Insert" }, { "t": "Space" }, { "t": "Str", "c": "Code" }, { "t": "Space" }, { "t": "Str", "c": "Chunk" }] }], + [{ "t": "Plain", "c": [{ "t": "Code", "c": [["", [], []], "Ctrl+Alt+I"] }] }], + [{ "t": "Plain", "c": [{ "t": "Code", "c": [["", [], []], "Cmd+Option+I"] }] }], + [ + { + "t": "Plain", + "c": [ + { "t": "Str", "c": "The" }, + { "t": "Space" }, + { "t": "Str", "c": "first" }, + { "t": "Space" }, + { "t": "Str", "c": "tab" }, + { "t": "Space" }, + { "t": "Str", "c": "stop" }, + { "t": "Space" }, + { "t": "Str", "c": "allows" }, + { "t": "Space" }, + { "t": "Str", "c": "for" }, + { "t": "Space" }, + { "t": "Str", "c": "easy" }, + { "t": "Space" }, + { "t": "Str", "c": "configuration," }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "second" }, + { "t": "Space" }, + { "t": "Str", "c": "for" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "actual" }, + { "t": "Space" }, + { "t": "Str", "c": "code" } + ] + } + ] + ], + [ + [{ "t": "Plain", "c": [{ "t": "Str", "c": "Knit" }] }], + [{ "t": "Plain", "c": [{ "t": "Code", "c": [["", [], []], "Ctrl+Shift+K"] }] }], + [{ "t": "Plain", "c": [{ "t": "Code", "c": [["", [], []], "Cmd+Shift+K"] }] }], + [ + { + "t": "Plain", + "c": [ + { "t": "Str", "c": "Knit" }, + { "t": "Space" }, + { "t": "Str", "c": "current" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], ".Rmd"] }, + { "t": "Space" }, + { "t": "Str", "c": "document" }, + { "t": "Space" }, + { "t": "Str", "c": "with" }, + { "t": "Space" }, + { "t": "Str", "c": "options" }, + { "t": "Space" }, + { "t": "Str", "c": "specified" }, + { "t": "Space" }, + { "t": "Str", "c": "in" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "YAML" }, + { "t": "Space" }, + { "t": "Str", "c": "frontmatter" } + ] + } + ] + ] + ] + ] + }, + { "t": "Header", "c": [2, ["snippets", [], []], [{ "t": "Str", "c": "Snippets" }]] }, + { "t": "Header", "c": [3, ["cross-referencing", [], []], [{ "t": "Str", "c": "Cross-referencing" }]] }, + { + "t": "Para", + "c": [ + { "t": "Code", "c": [["", [], []], "\\ref"] }, + { "t": "Space" }, + { "t": "Str", "c": "or" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "\\@ref"] }, + { "t": "Str", "c": ":" }, + { "t": "Space" }, + { "t": "Str", "c": "general" }, + { "t": "Space" }, + { "t": "Str", "c": "cross-reference;" }, + { "t": "Space" }, + { "t": "Str", "c": "inserts" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "\\@ref($1)"] }, + { "t": "SoftBreak" }, + { "t": "Code", "c": [["", [], []], "\\refsec"] }, + { "t": "Space" }, + { "t": "Str", "c": "or" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "\\@sec"] }, + { "t": "Str", "c": ":" }, + { "t": "Space" }, + { "t": "Str", "c": "section" }, + { "t": "Space" }, + { "t": "Str", "c": "cross-reference;" }, + { "t": "Space" }, + { "t": "Str", "c": "inserts" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "Section \\@ref($1)"] }, + { "t": "SoftBreak" }, + { "t": "Code", "c": [["", [], []], "\\reffig"] }, + { "t": "Space" }, + { "t": "Str", "c": "or" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "\\@fig"] }, + { "t": "Str", "c": ":" }, + { "t": "Space" }, + { "t": "Str", "c": "figure" }, + { "t": "Space" }, + { "t": "Str", "c": "cross-reference;" }, + { "t": "Space" }, + { "t": "Str", "c": "inserts" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "Figure \\@ref(fig:$1)"] }, + { "t": "SoftBreak" }, + { "t": "Code", "c": [["", [], []], "\\reftab"] }, + { "t": "Space" }, + { "t": "Str", "c": "or" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "\\@tab"] }, + { "t": "Str", "c": ":" }, + { "t": "Space" }, + { "t": "Str", "c": "table" }, + { "t": "Space" }, + { "t": "Str", "c": "cross-reference;" }, + { "t": "Space" }, + { "t": "Str", "c": "inserts" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "Table \\@ref(tab:$1)"] } + ] + }, + { "t": "Header", "c": [3, ["chunks", [], []], [{ "t": "Str", "c": "Chunks" }]] }, + { + "t": "Para", + "c": [ + { "t": "Code", "c": [["", [], []], "\\code"] }, + { "t": "Str", "c": ":" }, + { "t": "Space" }, + { "t": "Str", "c": "insert" }, + { "t": "Space" }, + { "t": "Str", "c": "a" }, + { "t": "Space" }, + { "t": "Str", "c": "code" }, + { "t": "Space" }, + { "t": "Str", "c": "chunk" }, + { "t": "SoftBreak" }, + { "t": "Code", "c": [["", [], []], "\\fig"] }, + { "t": "Str", "c": ":" }, + { "t": "Space" }, + { "t": "Str", "c": "insert" }, + { "t": "Space" }, + { "t": "Str", "c": "a" }, + { "t": "Space" }, + { "t": "Str", "c": "chunk" }, + { "t": "Space" }, + { "t": "Str", "c": "using" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "knitr::include_graphics()"] }, + { "t": "Space" }, + { "t": "Str", "c": "to" }, + { "t": "Space" }, + { "t": "Str", "c": "include" }, + { "t": "Space" }, + { "t": "Str", "c": "an" }, + { "t": "Space" }, + { "t": "Str", "c": "image;" }, + { "t": "Space" }, + { "t": "Str", "c": "hit" }, + { "t": "Space" }, + { "t": "Str", "c": "tabs" }, + { "t": "Space" }, + { "t": "Str", "c": "to" }, + { "t": "Space" }, + { "t": "Str", "c": "conviniently" }, + { "t": "Space" }, + { "t": "Str", "c": "fill" }, + { "t": "Space" }, + { "t": "Str", "c": "out" }, + { "t": "Space" }, + { "t": "Str", "c": "label," }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "fig.cap"] }, + { "t": "Space" }, + { "t": "Str", "c": "and" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "out.width"] }, + { "t": "Str", "c": "." } + ] + }, + { "t": "Header", "c": [1, ["bookdown-specific-features", [], []], [{ "t": "Str", "c": "Bookdown-Specific" }, { "t": "Space" }, { "t": "Str", "c": "Features" }]] }, + { + "t": "Para", + "c": [ + { "t": "Str", "c": "Before" }, + { "t": "Space" }, + { "t": "Str", "c": "you" }, + { "t": "Space" }, + { "t": "Str", "c": "can" }, + { "t": "Space" }, + { "t": "Str", "c": "use" }, + { "t": "Space" }, + { "t": "Str", "c": "blogdown-specific" }, + { "t": "Space" }, + { "t": "Str", "c": "features," }, + { "t": "Space" }, + { "t": "Str", "c": "you" }, + { "t": "Space" }, + { "t": "Str", "c": "need" }, + { "t": "Space" }, + { "t": "Str", "c": "to" }, + { "t": "Space" }, + { "t": "Str", "c": "first" }, + { "t": "Space" }, + { "t": "Str", "c": "open" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "directory" }, + { "t": "Space" }, + { "t": "Str", "c": "of" }, + { "t": "Space" }, + { "t": "Str", "c": "your" }, + { "t": "Space" }, + { "t": "Strong", "c": [{ "t": "Str", "c": "bookdown" }] }, + { "t": "Space" }, + { "t": "Str", "c": "project." }, + { "t": "Space" }, + { "t": "Str", "c": "The" }, + { "t": "Space" }, + { "t": "Str", "c": "easiest" }, + { "t": "Space" }, + { "t": "Str", "c": "way" }, + { "t": "Space" }, + { "t": "Str", "c": "is" }, + { "t": "Space" }, + { "t": "Str", "c": "to" }, + { "t": "Space" }, + { "t": "Str", "c": "use" }, + { "t": "Space" }, + { "t": "Str", "c": "RStudio’s" }, + { "t": "Space" }, + { "t": "Quoted", "c": [{ "t": "SingleQuote" }, [{ "t": "Str", "c": "New" }, { "t": "Space" }, { "t": "Str", "c": "Project" }]] }, + { "t": "Str", "c": "." } + ] + }, + { "t": "Header", "c": [2, ["serve-book", [], []], [{ "t": "Str", "c": "Serve" }, { "t": "Space" }, { "t": "Str", "c": "Book" }]] }, + { + "t": "OrderedList", + "c": [ + [1, { "t": "Decimal" }, { "t": "Period" }], + [ + [ + { + "t": "Plain", + "c": [ + { "t": "Str", "c": "In" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "command" }, + { "t": "Space" }, + { "t": "Str", "c": "palette" }, + { "t": "Space" }, + { "t": "Str", "c": "(" }, + { "t": "Code", "c": [["", [], []], "Ctrl/Cmd+Shift+P"] }, + { "t": "Str", "c": ")," }, + { "t": "Space" }, + { "t": "Str", "c": "search" }, + { "t": "Space" }, + { "t": "Str", "c": "for" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "serve book"] } + ] + } + ], + [{ "t": "Plain", "c": [{ "t": "Str", "c": "Execute" }, { "t": "Space" }, { "t": "Code", "c": [["", [], []], "Blogdown: Serve Site"] }] }], + [ + { + "t": "Plain", + "c": [ + { "t": "Str", "c": "Click" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "link" }, + { "t": "Space" }, + { "t": "Str", "c": "in" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "output" }, + { "t": "Space" }, + { "t": "Str", "c": "to" }, + { "t": "Space" }, + { "t": "Str", "c": "view" }, + { "t": "Space" }, + { "t": "Str", "c": "your" }, + { "t": "Space" }, + { "t": "Str", "c": "book" } + ] + } + ], + [ + { + "t": "Plain", + "c": [ + { + "t": "Strikeout", + "c": [ + { "t": "Str", "c": "You" }, + { "t": "Space" }, + { "t": "Str", "c": "are" }, + { "t": "Space" }, + { "t": "Str", "c": "redirected" }, + { "t": "Space" }, + { "t": "Str", "c": "to" }, + { "t": "Space" }, + { "t": "Str", "c": "your" }, + { "t": "Space" }, + { "t": "Str", "c": "new" }, + { "t": "Space" }, + { "t": "Str", "c": "site" }, + { "t": "Space" }, + { "t": "Str", "c": "(not" }, + { "t": "Space" }, + { "t": "Str", "c": "implemented" }, + { "t": "Space" }, + { "t": "Str", "c": "yet)!" } + ] + } + ] + } + ] + ] + ] + }, + { "t": "Header", "c": [1, ["blogdown-specific-features", [], []], [{ "t": "Str", "c": "Blogdown-Specific" }, { "t": "Space" }, { "t": "Str", "c": "Features" }]] }, + { + "t": "Para", + "c": [ + { "t": "Str", "c": "Before" }, + { "t": "Space" }, + { "t": "Str", "c": "you" }, + { "t": "Space" }, + { "t": "Str", "c": "can" }, + { "t": "Space" }, + { "t": "Str", "c": "use" }, + { "t": "Space" }, + { "t": "Str", "c": "blogdown-specific" }, + { "t": "Space" }, + { "t": "Str", "c": "features," }, + { "t": "Space" }, + { "t": "Str", "c": "you" }, + { "t": "Space" }, + { "t": "Str", "c": "need" }, + { "t": "Space" }, + { "t": "Str", "c": "to" }, + { "t": "Space" }, + { "t": "Str", "c": "first" }, + { "t": "Space" }, + { "t": "Str", "c": "open" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "directory" }, + { "t": "Space" }, + { "t": "Str", "c": "of" }, + { "t": "Space" }, + { "t": "Str", "c": "your" }, + { "t": "Space" }, + { "t": "Strong", "c": [{ "t": "Str", "c": "blogdown" }] }, + { "t": "Space" }, + { "t": "Str", "c": "project." }, + { "t": "Space" }, + { "t": "Str", "c": "The" }, + { "t": "Space" }, + { "t": "Str", "c": "easiest" }, + { "t": "Space" }, + { "t": "Str", "c": "way" }, + { "t": "Space" }, + { "t": "Str", "c": "is" }, + { "t": "Space" }, + { "t": "Str", "c": "to" }, + { "t": "Space" }, + { "t": "Str", "c": "use" }, + { "t": "Space" }, + { "t": "Str", "c": "RStudio’s" }, + { "t": "Space" }, + { "t": "Quoted", "c": [{ "t": "SingleQuote" }, [{ "t": "Str", "c": "New" }, { "t": "Space" }, { "t": "Str", "c": "Project" }]] }, + { "t": "Str", "c": "." } + ] + }, + { "t": "RawBlock", "c": ["html", ""] }, + { "t": "Header", "c": [2, ["new-post", [], []], [{ "t": "Str", "c": "New" }, { "t": "Space" }, { "t": "Str", "c": "Post" }]] }, + { + "t": "OrderedList", + "c": [ + [1, { "t": "Decimal" }, { "t": "Period" }], + [ + [ + { + "t": "Plain", + "c": [ + { "t": "Str", "c": "In" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "command" }, + { "t": "Space" }, + { "t": "Str", "c": "palette" }, + { "t": "Space" }, + { "t": "Str", "c": "(" }, + { "t": "Code", "c": [["", [], []], "Ctrl/Cmd+Shift+P"] }, + { "t": "Str", "c": ")," }, + { "t": "Space" }, + { "t": "Str", "c": "search" }, + { "t": "Space" }, + { "t": "Str", "c": "for" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "new post"] } + ] + } + ], + [ + { + "t": "Plain", + "c": [ + { "t": "Str", "c": "Execute" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "Blogdown: New Post"] }, + { "t": "Str", "c": "," }, + { "t": "Space" }, + { "t": "Str", "c": "then" }, + { "t": "Space" }, + { "t": "Str", "c": "fill" }, + { "t": "Space" }, + { "t": "Str", "c": "out" }, + { "t": "Space" }, + { "t": "Str", "c": "basic" }, + { "t": "Space" }, + { "t": "Str", "c": "information" }, + { "t": "Space" }, + { "t": "Str", "c": "(title," }, + { "t": "Space" }, + { "t": "Str", "c": "author," }, + { "t": "Space" }, + { "t": "Str", "c": "category," }, + { "t": "Space" }, + { "t": "Str", "c": "archetype)" } + ] + }, + { + "t": "BulletList", + "c": [ + [ + { + "t": "Plain", + "c": [ + { "t": "Str", "c": "You" }, + { "t": "Space" }, + { "t": "Str", "c": "can" }, + { "t": "Space" }, + { "t": "Str", "c": "set" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "default" }, + { "t": "Space" }, + { "t": "Str", "c": "author" }, + { "t": "Space" }, + { "t": "Str", "c": "in" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "settings" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "Ctrl/Cmd + ,"] } + ] + } + ] + ] + } + ], + [{ "t": "Plain", "c": [{ "t": "Str", "c": "You" }, { "t": "Space" }, { "t": "Str", "c": "are" }, { "t": "Space" }, { "t": "Str", "c": "redirected" }, { "t": "Space" }, { "t": "Str", "c": "to" }, { "t": "Space" }, { "t": "Str", "c": "your" }, { "t": "Space" }, { "t": "Str", "c": "new" }, { "t": "Space" }, { "t": "Str", "c": "post!" }] }] + ] + ] + }, + { + "t": "Para", + "c": [ + { + "t": "Image", + "c": [ + ["", [], []], + [{ "t": "Str", "c": "blogdown" }, { "t": "Space" }, { "t": "Str", "c": "new" }, { "t": "Space" }, { "t": "Str", "c": "post" }, { "t": "Space" }, { "t": "Str", "c": "demo" }], + ["images/demo/blogdown/newpost.gif", "fig:"] + ] + } + ] + }, + { "t": "Header", "c": [2, ["serve-site", [], []], [{ "t": "Str", "c": "Serve" }, { "t": "Space" }, { "t": "Str", "c": "Site" }]] }, + { + "t": "OrderedList", + "c": [ + [1, { "t": "Decimal" }, { "t": "Period" }], + [ + [ + { + "t": "Plain", + "c": [ + { "t": "Str", "c": "In" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "command" }, + { "t": "Space" }, + { "t": "Str", "c": "palette" }, + { "t": "Space" }, + { "t": "Str", "c": "(" }, + { "t": "Code", "c": [["", [], []], "Ctrl/Cmd+Shift+P"] }, + { "t": "Str", "c": ")," }, + { "t": "Space" }, + { "t": "Str", "c": "search" }, + { "t": "Space" }, + { "t": "Str", "c": "for" }, + { "t": "Space" }, + { "t": "Code", "c": [["", [], []], "serve site"] } + ] + } + ], + [{ "t": "Plain", "c": [{ "t": "Str", "c": "Execute" }, { "t": "Space" }, { "t": "Code", "c": [["", [], []], "Blogdown: Serve Site"] }] }], + [ + { + "t": "Plain", + "c": [ + { "t": "Str", "c": "Click" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "link" }, + { "t": "Space" }, + { "t": "Str", "c": "in" }, + { "t": "Space" }, + { "t": "Str", "c": "the" }, + { "t": "Space" }, + { "t": "Str", "c": "output" }, + { "t": "Space" }, + { "t": "Str", "c": "to" }, + { "t": "Space" }, + { "t": "Str", "c": "view" }, + { "t": "Space" }, + { "t": "Str", "c": "your" }, + { "t": "Space" }, + { "t": "Str", "c": "blog" } + ] + } + ], + [ + { + "t": "Plain", + "c": [ + { + "t": "Strikeout", + "c": [ + { "t": "Str", "c": "You" }, + { "t": "Space" }, + { "t": "Str", "c": "are" }, + { "t": "Space" }, + { "t": "Str", "c": "redirected" }, + { "t": "Space" }, + { "t": "Str", "c": "to" }, + { "t": "Space" }, + { "t": "Str", "c": "your" }, + { "t": "Space" }, + { "t": "Str", "c": "new" }, + { "t": "Space" }, + { "t": "Str", "c": "site" }, + { "t": "Space" }, + { "t": "Str", "c": "(not" }, + { "t": "Space" }, + { "t": "Str", "c": "implemented" }, + { "t": "Space" }, + { "t": "Str", "c": "yet)!" } + ] + } + ] + } + ] + ] + ] + }, + { "t": "Header", "c": [1, ["other-markdown-features", [], []], [{ "t": "Str", "c": "Other" }, { "t": "Space" }, { "t": "Str", "c": "Markdown" }, { "t": "Space" }, { "t": "Str", "c": "Features" }]] }, + { "t": "Header", "c": [2, ["syntax-highlighting", [], []], [{ "t": "Str", "c": "Syntax" }, { "t": "Space" }, { "t": "Str", "c": "Highlighting" }]] }, + { + "t": "Para", + "c": [ + { "t": "Str", "c": "Mostly" }, + { "t": "Space" }, + { "t": "Str", "c": "adapted" }, + { "t": "Space" }, + { "t": "Str", "c": "from" }, + { "t": "Space" }, + { "t": "Link", "c": [["", [], []], [{ "t": "Str", "c": "microsoft/vscode" }], ["https://github.com/microsoft/vscode/tree/master/extensions/markdown-language-features", ""]] }, + { "t": "Space" }, + { "t": "Str", "c": "and" }, + { "t": "Space" }, + { "t": "Link", "c": [["", [], []], [{ "t": "Str", "c": "yzhang-gh/vscode-markdown" }], ["https://github.com/yzhang-gh/vscode-markdown", ""]] }, + { "t": "Str", "c": "." } + ] + }, + { "t": "Header", "c": [2, ["keyboard-shortcuts-1", [], []], [{ "t": "Str", "c": "Keyboard" }, { "t": "Space" }, { "t": "Str", "c": "Shortcuts" }]] }, + { "t": "Para", "c": [{ "t": "Str", "c": "Mostly" }, { "t": "Space" }, { "t": "Str", "c": "adapted" }, { "t": "Space" }, { "t": "Str", "c": "from" }, { "t": "Space" }, { "t": "Link", "c": [["", [], []], [{ "t": "Str", "c": "yzhang-gh/vscode-markdown" }], ["https://github.com/yzhang-gh/vscode-markdown", ""]] }, { "t": "Str", "c": "." }] }, + { + "t": "Table", + "c": [ + [], + [{ "t": "AlignCenter" }, { "t": "AlignCenter" }, { "t": "AlignCenter" }, { "t": "AlignCenter" }], + [0, 0, 0, 0], + [[{ "t": "Plain", "c": [{ "t": "Str", "c": "Description" }] }], [{ "t": "Plain", "c": [{ "t": "Str", "c": "Windows/Linux" }] }], [{ "t": "Plain", "c": [{ "t": "Str", "c": "Mac" }] }], [{ "t": "Plain", "c": [{ "t": "Str", "c": "Note" }] }]], + [ + [[{ "t": "Plain", "c": [{ "t": "Str", "c": "toggle" }, { "t": "Space" }, { "t": "Str", "c": "bold" }] }], [{ "t": "Plain", "c": [{ "t": "Code", "c": [["", [], []], "Ctrl + B"] }] }], [{ "t": "Plain", "c": [{ "t": "Code", "c": [["", [], []], "Cmd + B"] }] }], []], + [[{ "t": "Plain", "c": [{ "t": "Str", "c": "toggle" }, { "t": "Space" }, { "t": "Str", "c": "italics" }] }], [{ "t": "Plain", "c": [{ "t": "Code", "c": [["", [], []], "Ctrl + I"] }] }], [{ "t": "Plain", "c": [{ "t": "Code", "c": [["", [], []], "Cmd + I"] }] }], []] + ] + ] + }, + { "t": "Header", "c": [1, ["todo", [], []], [{ "t": "Str", "c": "TODO" }]] }, + { + "t": "BulletList", + "c": [ + [ + { "t": "Plain", "c": [{ "t": "Str", "c": "general" }] }, + { + "t": "BulletList", + "c": [ + [ + { + "t": "Plain", + "c": [ + { "t": "Str", "c": "adapt" }, + { "t": "Space" }, + { "t": "Str", "c": "and" }, + { "t": "Space" }, + { "t": "Str", "c": "modify" }, + { "t": "Space" }, + { "t": "Str", "c": "existing" }, + { "t": "Space" }, + { "t": "Str", "c": "markdown" }, + { "t": "Space" }, + { "t": "Str", "c": "support" }, + { "t": "Space" }, + { "t": "Str", "c": "extensions" }, + { "t": "SoftBreak" }, + { "t": "Str", "c": "preview" }, + { "t": "Space" }, + { "t": "Str", "c": "HTML/PDF" } + ] + } + ], + [{ "t": "Plain", "c": [{ "t": "Str", "c": "insert" }, { "t": "Space" }, { "t": "Str", "c": "tables" }, { "t": "Space" }, { "t": "Str", "c": "(with" }, { "t": "Space" }, { "t": "Str", "c": "labels" }, { "t": "Space" }, { "t": "Str", "c": "and" }, { "t": "Space" }, { "t": "Str", "c": "captions)" }] }], + [{ "t": "Plain", "c": [{ "t": "Str", "c": "citation" }, { "t": "Space" }, { "t": "Str", "c": "autocompletion" }] }] + ] + } + ], + [{ "t": "Plain", "c": [{ "t": "Str", "c": "bookdown" }, { "t": "Space" }, { "t": "Str", "c": "support" }] }], + [{ "t": "Plain", "c": [{ "t": "Str", "c": "blogdown" }, { "t": "Space" }, { "t": "Str", "c": "support" }] }] + ] + }, + { "t": "Header", "c": [1, ["change-log", [], []], [{ "t": "Str", "c": "Change" }, { "t": "Space" }, { "t": "Str", "c": "Log" }]] }, + { "t": "Para", "c": [{ "t": "Str", "c": "See" }, { "t": "Space" }, { "t": "Link", "c": [["", [], []], [{ "t": "Str", "c": "CHANGELOG.md" }], ["./CHANGELOG.md", ""]] }] } + ], + "pandoc-api-version": [1, 17, 5, 1], + "meta": {} +} diff --git a/images/demo/table-format.gif b/images/demo/table-format.gif new file mode 100644 index 0000000..002166a Binary files /dev/null and b/images/demo/table-format.gif differ diff --git a/package-lock.json b/package-lock.json index 3b4d3d7..85bd83d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "rmarkdown", - "version": "0.0.6", + "version": "0.0.8", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -872,6 +872,11 @@ "type-fest": "^0.8.1" } }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" + }, "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", diff --git a/package.json b/package.json index 2741d36..33cbd96 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "type": "git", "url": "https://github.com/TianyiShi2001/rmarkdown-vscode.git" }, - "version": "0.0.8", + "version": "0.0.9", "engines": { "vscode": "^1.44.0" }, @@ -199,6 +199,7 @@ }, "dependencies": { "chalk": "^4.0.0", + "grapheme-splitter": "^1.0.4", "r-helper": "0.0.4", "rmarkdown": "0.0.3" } diff --git a/src/extension.ts b/src/extension.ts index a678b92..21db94b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3,6 +3,7 @@ import { Rmarkdown } from "./rmarkdown"; import * as decorations from "./rmarkdown-core/decorations"; import * as listEditing from "./rmarkdown-core/listEditing"; import * as formatting from "./rmarkdown-core/formatting"; +import * as tableFormatter from "./rmarkdown-core/tableFormatter"; import { loadCommands } from "./auto"; // this method is called when your extension is activated @@ -13,6 +14,7 @@ export function activate(context: vscode.ExtensionContext) { decorations.activate(context); listEditing.activate(context); formatting.activate(context); + tableFormatter.activate(context); loadCommands(context); diff --git a/src/rmarkdown-core/tableFormatter.ts b/src/rmarkdown-core/tableFormatter.ts new file mode 100644 index 0000000..b3d4130 --- /dev/null +++ b/src/rmarkdown-core/tableFormatter.ts @@ -0,0 +1,194 @@ +// https://github.github.com/gfm/#tables-extension- + +import { CancellationToken, Disposable, DocumentFormattingEditProvider, EndOfLine, ExtensionContext, FormattingOptions, languages, Range, TextDocument, TextEdit, workspace } from "vscode"; +import { rmdDocSelector } from "../utils"; +//// This module can only be referenced with ECMAScript imports/exports by turning on the 'esModuleInterop' flag and referencing its default export. +//import * as GraphemeSplitter from "grapheme-splitter"; +import GraphemeSplitter = require("grapheme-splitter"); + +const splitter = new GraphemeSplitter(); + +export function activate(_: ExtensionContext) { + let registration: Disposable | undefined; + + function registerFormatterIfEnabled() { + const isEnabled = true; //workspace.getConfiguration().get("rmarkdown_vscode.rmarkdown-core.tableFormatter.enabled", true); + if (isEnabled && !registration) { + registration = languages.registerDocumentFormattingEditProvider(rmdDocSelector, new RmarkdownDocumentFormatter()); + } else if (!isEnabled && registration) { + registration.dispose(); + registration = undefined; + } + } + + registerFormatterIfEnabled(); + + workspace.onDidChangeConfiguration((event) => { + if (event.affectsConfiguration("markdown.extension.tableFormatter.enabled")) { + registerFormatterIfEnabled(); + } + }); +} + +export function deactivate() {} + +class RmarkdownDocumentFormatter implements DocumentFormattingEditProvider { + public provideDocumentFormattingEdits(document: TextDocument, options: FormattingOptions, token: CancellationToken): TextEdit[] | Thenable { + let edits: TextEdit[] = []; + let tables = this.detectTables(document.getText()); + if (tables !== null) { + tables.forEach((table) => { + edits.push(new TextEdit(this.getRange(document, table), this.formatTable(table, document, options))); + }); + return edits; + } else { + return []; + } + } + + private detectTables(text: string) { + const lineBreak = "\\r?\\n"; + const contentLine = "\\|?.*\\|.*\\|?"; + + const leftSideHyphenComponent = "(?:\\|? *:?-+:? *\\|)"; + const middleHyphenComponent = "(?: *:?-+:? *\\|)*"; + const rightSideHyphenComponent = "(?: *:?-+:? *\\|?)"; + const multiColumnHyphenLine = leftSideHyphenComponent + middleHyphenComponent + rightSideHyphenComponent; + + //// GitHub issue #431 + const singleColumnHyphenLine = "(?:\\| *:?-+:? *\\|)"; + + const hyphenLine = "[ \\t]*(?:" + multiColumnHyphenLine + "|" + singleColumnHyphenLine + ")[ \\t]*"; + + const tableRegex = new RegExp(contentLine + lineBreak + hyphenLine + "(?:" + lineBreak + contentLine + ")*", "g"); + return text.match(tableRegex); + } + + private getRange(document: TextDocument, text: string) { + let documentText = document.getText(); + let start = document.positionAt(documentText.indexOf(text)); + let end = document.positionAt(documentText.indexOf(text) + text.length); + return new Range(start, end); + } + + /** + * Return the indentation of a table as a string of spaces by reading it from the first line. + * In case of `markdown.extension.table.normalizeIndentation` is `enabled` it is rounded to the closest multiple of + * the configured `tabSize`. + */ + private getTableIndentation(text: string, options: FormattingOptions) { + let doNormalize = workspace.getConfiguration("markdown.extension.tableFormatter").get("normalizeIndentation"); + let indentRegex = new RegExp(/^(\s*)\S/u); + let match = text.match(indentRegex)!; + let spacesInFirstLine = match[1].length; + let tabStops = Math.round(spacesInFirstLine / options.tabSize); + let spaces = doNormalize ? " ".repeat(options.tabSize * tabStops) : " ".repeat(spacesInFirstLine); + return spaces; + } + + private formatTable(text: string, doc: TextDocument, options: FormattingOptions) { + let indentation = this.getTableIndentation(text, options); + + let rows: string[] = []; + let rowsNoIndentPattern = new RegExp(/^\s*(\S.*)$/gmu); + let match = null; + while ((match = rowsNoIndentPattern.exec(text)) !== null) { + rows.push(match[1].trim()); + } + + // Desired width of each column + let colWidth: number[] = []; + // Alignment of each column + let colAlign: Array<"c" | "l" | "r"> = []; + // Regex to extract cell content. + // Known issue: `\\|` is not correctly parsed as a valid delimiter + let fieldRegExp = new RegExp(/(?:((?:\\\||`.*?`|[^\|])*)\|)/gu); + let cjkRegex = /[\u3000-\u9fff\uff01-\uff60]/g; + + let lines = rows.map((row, num) => { + // Normalize + if (row.startsWith("|")) { + row = row.slice(1); + } + if (!row.endsWith("|")) { + row = row + "|"; + } + + let field = null; + let values = []; + let i = 0; + while ((field = fieldRegExp.exec(row)) !== null) { + let cell = field[1].trim(); + values.push(cell); + + //// Calculate `colWidth` + //// Ignore length of dash-line to enable width reduction + if (num !== 1) { + //// Treat CJK characters as 2 English ones because of Unicode stuff + const numOfUnicodeChars = splitter.countGraphemes(cell); + const width = cjkRegex.test(cell) ? numOfUnicodeChars + cell.match(cjkRegex)!.length : numOfUnicodeChars; + colWidth[i] = colWidth[i] > width ? colWidth[i] : width; + } + + i++; + } + return values; + }); + + // Normalize the num of hyphen, use Math.max to determine minimum length based on dash-line format + lines[1] = lines[1].map((cell, i) => { + if (/:-+:/.test(cell)) { + //:---: + colWidth[i] = Math.max(colWidth[i], 5); + colAlign[i] = "c"; + return ":" + "-".repeat(colWidth[i] - 2) + ":"; + } else if (/:-+/.test(cell)) { + //:--- + colWidth[i] = Math.max(colWidth[i], 4); + colAlign[i] = "l"; + return ":" + "-".repeat(colWidth[i] - 1); + } else if (/-+:/.test(cell)) { + //---: + colWidth[i] = Math.max(colWidth[i], 4); + colAlign[i] = "r"; + return "-".repeat(colWidth[i] - 1) + ":"; + } else if (/-+/.test(cell)) { + //--- + colWidth[i] = Math.max(colWidth[i], 3); + colAlign[i] = "l"; + return "-".repeat(colWidth[i]); + } else { + colAlign[i] = "l"; + } + }) as string[]; + + return lines + .map((row) => { + let cells = row.map((cell, i) => { + const desiredWidth = colWidth[i]; + let jsLength = splitter + .splitGraphemes(cell + " ".repeat(desiredWidth)) + .slice(0, desiredWidth) + .join("").length; + + if (cjkRegex.test(cell)) { + jsLength -= cell.match(cjkRegex)!.length; + } + + return this.alignText(cell, colAlign[i], jsLength); + }); + return indentation + "| " + cells.join(" | ") + " |"; + }) + .join(doc.eol === EndOfLine.LF ? "\n" : "\r\n"); + } + + private alignText(text: string, align: string, length: number) { + if (align === "c" && length > text.length) { + return (" ".repeat(Math.floor((length - text.length) / 2)) + text + " ".repeat(length)).slice(0, length); + } else if (align === "r") { + return (" ".repeat(length) + text).slice(-length); + } else { + return (text + " ".repeat(length)).slice(0, length); + } + } +} diff --git a/src/utils.ts b/src/utils.ts index 07bf30e..f3f4ccc 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,6 +1,6 @@ -export { isInFencedCodeBlock } from './utils/fencedCodeBlock'; -export { isFileTooLarge } from './utils/sizeCheck'; -export { verbatimOutput } from './utils/verbatimOutput'; -export { mathEnvCheck } from './utils/mathEnv'; -export { slugify } from './utils/slugify'; -export { isRmarkdownEditor } from './utils/misc'; +export { isInFencedCodeBlock } from "./utils/fencedCodeBlock"; +export { isFileTooLarge } from "./utils/sizeCheck"; +export { verbatimOutput } from "./utils/verbatimOutput"; +export { mathEnvCheck } from "./utils/mathEnv"; +export { slugify } from "./utils/slugify"; +export { isRmarkdownEditor, rmdDocSelector } from "./utils/misc"; diff --git a/src/utils/misc.ts b/src/utils/misc.ts index 819cbcd..83459d5 100644 --- a/src/utils/misc.ts +++ b/src/utils/misc.ts @@ -3,3 +3,9 @@ import { TextEditor } from "vscode"; export function isRmarkdownEditor(editor: TextEditor) { return editor && editor.document && editor.document.languageId === "rmarkdown"; } + +/** Scheme `File` or `Untitled` */ +export const rmdDocSelector = [ + { language: "rmarkdown", scheme: "file" }, + { language: "rmarkdown", scheme: "untitled" }, +];