-
Notifications
You must be signed in to change notification settings - Fork 81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve html preview #470
Improve html preview #470
Changes from all commits
2e5083b
a9985a2
cd1a508
11eca0d
cbea199
c5747ca
60a18aa
5679f01
138cf91
628274e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -182,26 +182,21 @@ reprex_render_impl <- function(input, | |
invisible(reprex_file) | ||
} | ||
|
||
# heavily influenced by the post_processor() function of github_document() | ||
# influenced by the post_processor() function of github_document() | ||
# but with substantial reprex-specific updates in 2024-09 | ||
preview <- function(input) { | ||
css <- rmarkdown::pandoc_path_arg( | ||
mode <- if (is_dark_mode()) "dark" else "light" | ||
res_dir <- rmarkdown::pandoc_path_arg( | ||
path_package( | ||
"rmarkdown", | ||
"rmarkdown/templates/github_document/resources/github.css" | ||
) | ||
) | ||
css <- glue("github-markdown-css:{css}") | ||
template <- rmarkdown::pandoc_path_arg( | ||
path_package( | ||
"rmarkdown", | ||
"rmarkdown/templates/github_document/resources/preview.html" | ||
"reprex", | ||
glue("rmarkdown/templates/reprex_document/resources") | ||
) | ||
) | ||
args <- c( | ||
"--standalone", "--self-contained", | ||
"--highlight-style", "pygments", | ||
"--template", template, | ||
"--variable", css, | ||
"--standalone", "--embed-resources", | ||
"--highlight-style", path(res_dir, glue("starry-nights-{mode}.theme")), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Previously, the |
||
"--css", path(res_dir, glue("github-{mode}.css")), | ||
"--syntax-definition", path(res_dir, "r.xml"), | ||
Comment on lines
+198
to
+199
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No more template. I'm providing the github css in a way that works with the default html template. Plus a new custom syntax definition. |
||
"--metadata", "pagetitle=PREVIEW", | ||
"--quiet" | ||
) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,3 +63,12 @@ | |
is_testing <- function() { | ||
identical(Sys.getenv("TESTTHAT"), "true") | ||
} | ||
|
||
is_dark_mode <- function() { | ||
if (rstudioapi::isAvailable() && rstudioapi::hasFun("getThemeInfo")) { | ||
theme_info <- rstudioapi::getThemeInfo() | ||
theme_info$dark | ||
} else { | ||
FALSE | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Positron ends up here unconditionally today ( |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# use the CSS found here: | ||
# https://github.com/sindresorhus/github-markdown-css | ||
# which aims to be: | ||
# "The minimal amount of CSS to replicate the GitHub Markdown style" | ||
|
||
library(usethis) | ||
|
||
use_directory("inst/rmarkdown/templates/reprex_document/resources") | ||
|
||
use_github_file( | ||
repo_spec = "sindresorhus/github-markdown-css", | ||
path = "github-markdown-dark.css", | ||
save_as = "inst/rmarkdown/templates/reprex_document/resources/github-dark.css" | ||
) | ||
|
||
use_github_file( | ||
repo_spec = "sindresorhus/github-markdown-css", | ||
path = "github-markdown-light.css", | ||
save_as = "inst/rmarkdown/templates/reprex_document/resources/github-light.css" | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
# write Pandoc's default (pygments) highlight style to a JSON file | ||
# pandoc --print-highlight-style pygments > data-raw/pygments.theme | ||
# use this as a scaffold, but modify colors to match the Starry Night theme | ||
# that GitHub uses | ||
|
||
library(tidyverse) | ||
|
||
pyg <- jsonlite::fromJSON("data-raw/pygments.theme") | ||
pyg |> pluck("text-styles") |> names() | ||
|
||
# How does Pandoc do syntax highlighting? | ||
# https://pandoc.org/chunkedhtml-demo/13-syntax-highlighting.html | ||
# "The Haskell library skylighting is used for highlighting." | ||
|
||
# Pandoc/skylighting store themes using the | ||
# Syntax-Highlighting framework from KDE Frameworks | ||
|
||
# Learn the meaning of the styles (classes) supported by Pandoc here: | ||
# https://docs.kde.org/stable5/en/kate/katepart/highlight.html | ||
# see "Available Default Styles" | ||
# https://docs.kde.org/stable5/en/kate/katepart/color-themes.html | ||
# see "Default Text Styles" | ||
|
||
# this is me taking the styles Pandoc/skylighting expects, | ||
# noting what they are meant for conceptually, | ||
# and picking the starry-night color alias/variable that seems the best fit | ||
|
||
x <- str_glue(' | ||
Alert,"Text style for special words in comments, such as TODO, FIXME, XXXX and WARNING.",\\ | ||
comment, | ||
Annotation,"Text style for annotations in comments or documentation commands, such as @param in Doxygen or JavaDoc.",\\ | ||
comment, | ||
Attribute,"Text style for annotations or attributes of functions or objects, e.g. @override in Java, or __declspec(...) and __attribute__((...)) in C++.",\\ | ||
entity-tag, | ||
BaseN,"(Base-N Integer): Text style for numbers with base other than 10.",\\ | ||
constant, | ||
BuiltIn,"(Built-in): Text style for built-in language classes, functions and objects.",\\ | ||
entity, | ||
Char,"(Character): Text style for single characters such as \'x\'.",\\ | ||
string, | ||
Comment, "Text style for normal comments.",\\ | ||
comment, | ||
CommentVar,"(Comment Variable): Text style that refers to variables names used in above commands in a comment, such as foobar in \'@param foobar\', in Doxygen or JavaDoc.",\\ | ||
comment, | ||
Constant,"Text style for language constants and user defined constants, e.g. True, False, None in Python or nullptr in C/C++; or math constants like PI.",\\ | ||
constant, | ||
ControlFlow,"(Control Flow): Text style for control flow keywords, such as if, then, else, return, switch, break, yield, continue, etc.",\\ | ||
keyword, | ||
DataType,"(Data Type): Text style for built-in data types such as int, char, float, void, u64, etc.",\\ | ||
constant, | ||
DecVal,"(Decimal/Value): Text style for decimal values.",\\ | ||
constant, | ||
Documentation,"Text style for comments that reflect API documentation, such as /** doxygen comments */ or \"\"\"docstrings\"\"\".",\\ | ||
comment, | ||
Error,"Text style indicating error highlighting and wrong syntax.",\\ | ||
invalid-illegal-text,invalid-illegal-bg | ||
Extension,"Text style for well-known extensions, such as Qt™ classes, functions/macros in C++ and Python or boost.",\\ | ||
entity, | ||
Float,"(Floating Point): Text style for floating point numbers.",\\ | ||
constant, | ||
Function,"Text style for function definitions and function calls.",\\ | ||
entity, | ||
Import,"(Imports, Modules, Includes): Text style for includes, imports, modules or LATEX packages.",\\ | ||
storage-modifier-import, | ||
Information,"Text style for information, notes and tips, such as the keyword @note in Doxygen.",\\ | ||
comment, | ||
Keyword,"Text style for built-in language keywords.",\\ | ||
keyword, | ||
Operator,"Text style for operators, such as +, -, *, /, %, etc.",\\ | ||
keyword, | ||
Others,"Text style for attributes that do not match any of the other default styles.",\\ | ||
, | ||
Preprocessor,"Text style for preprocessor statements or macro definitions.",\\ | ||
keyword, | ||
SpecialChar,"(Special Character): Text style for escaped characters in strings, e.g. \"hello\\n\", and other characters with special meaning in strings, such as substitutions or regex operators.",\\ | ||
carriage-return-text,carriage-return-bg | ||
SpecialString,"(Special String): Text style for special strings, such as regular expressions in ECMAScript, the LATEX math mode, SQL, etc.",\\ | ||
string-regexp, | ||
String,"Text style for strings like \"hello world\".",\\ | ||
string, | ||
Variable,"Text style for variables, if applicable. For instance, variables in PHP/Perl typically start with a $, so all identifiers following the pattern $foo are highlighted as variable.",\\ | ||
variable, | ||
VerbatimString,"(Verbatim String): Text style for verbatim or raw strings like \'raw \backlash\' in Perl, CoffeeScript, and shells, as well as r\'\raw\' in Python, or such as HERE docs.",\\ | ||
string, | ||
Warning,"Text style for warnings, such as the keyword @warning in Doxygen.",\\ | ||
comment, | ||
') | ||
|
||
dat <- read_csv(x, col_names = c("pyg_class", "pyg_note", "pl_text_style", "pl_background_style")) | ||
dat | ||
|
||
# get the starry-night css in order to excavate the colors | ||
use_github_file( | ||
repo_spec = "wooorm/starry-night", | ||
path = "style/dark.css", | ||
save_as = "data-raw/starry-night-dark.css" | ||
) | ||
|
||
use_github_file( | ||
repo_spec = "wooorm/starry-night", | ||
path = "style/light.css", | ||
save_as = "data-raw/starry-night-light.css" | ||
) | ||
|
||
raw_css_lines <- readLines("data-raw/starry-night-light.css") | ||
sn_light <- raw_css_lines |> | ||
str_subset(" --color-prettylights-syntax-") |> | ||
tibble() |> | ||
set_names("raw") |> | ||
mutate(comment = str_extract(raw, ".+:")) |> | ||
mutate(color = str_extract(raw, "#[0-9a-fA-F]{6}")) |> | ||
mutate(comment = str_remove(comment, " --color-prettylights-syntax-")) |> | ||
mutate(comment = str_remove(comment, ":$")) |> | ||
select(comment, color) | ||
|
||
raw_css_lines <- readLines("data-raw/starry-night-dark.css") | ||
sn_dark <- raw_css_lines |> | ||
str_subset(" --color-prettylights-syntax-") |> | ||
tibble() |> | ||
set_names("raw") |> | ||
mutate(comment = str_extract(raw, ".+:")) |> | ||
mutate(color = str_extract(raw, "#[0-9a-fA-F]{6}")) |> | ||
mutate(comment = str_remove(comment, " --color-prettylights-syntax-")) |> | ||
mutate(comment = str_remove(comment, ":$")) |> | ||
select(comment, color) | ||
|
||
dat | ||
sn_light | ||
sn_dark | ||
|
||
dat_light <- dat |> | ||
rename(cls = pyg_class) |> | ||
select(-pyg_note) |> | ||
left_join( | ||
sn_light, | ||
by = join_by(pl_text_style == comment) | ||
) |> | ||
rename(txt_col = color) |> | ||
left_join( | ||
sn_light, | ||
by = join_by(pl_background_style == comment) | ||
) |> | ||
rename(bg_col = color) |> | ||
select(-starts_with("pl_")) | ||
dat_light | ||
|
||
dat_dark <- dat |> | ||
rename(cls = pyg_class) |> | ||
select(-pyg_note) |> | ||
left_join( | ||
sn_dark, | ||
by = join_by(pl_text_style == comment) | ||
) |> | ||
rename(txt_col = color) |> | ||
left_join( | ||
sn_dark, | ||
by = join_by(pl_background_style == comment) | ||
) |> | ||
rename(bg_col = color) |> | ||
select(-starts_with("pl_")) | ||
dat_dark | ||
|
||
g <- function(cls, txt_col, bg_col) { | ||
list( | ||
`text-color` = txt_col, | ||
`background-color` = bg_col, | ||
bold = FALSE, | ||
italic = FALSE, | ||
underline = FALSE | ||
) | ||
} | ||
|
||
theme_light <- theme_dark <- pyg | ||
theme_light[["text-styles"]] <- dat_light |> | ||
pmap(g) |> | ||
set_names(dat_light$cls) | ||
theme_dark[["text-styles"]] <- dat_dark |> | ||
pmap(g) |> | ||
set_names(dat_dark$cls) | ||
|
||
jsonlite::write_json( | ||
theme_light, | ||
"inst/rmarkdown/templates/reprex_document/resources/starry-nights-light.theme", | ||
null = "null", | ||
auto_unbox = TRUE, | ||
pretty = TRUE | ||
) | ||
|
||
jsonlite::write_json( | ||
theme_dark, | ||
"inst/rmarkdown/templates/reprex_document/resources/starry-nights-dark.theme", | ||
null = "null", | ||
auto_unbox = TRUE, | ||
pretty = TRUE | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently this is just how modern Pandoc calls should look.