1
#' Set or get theme to use for syntax highlighting
2
#' @noRd
3
#' @author Ramnath Vaidyanathan
4
set_theme = function(theme) {
5 0
  header = if (is.list(theme)) theme else theme_to_header(theme)
6 0
  opts_chunk$set(background = header$background)
7 0
  set_header(highlight = header$highlight)
8
  # par(col = theme$foreground)
9
}
10
get_theme = function(theme = NULL) {
11 0
  if (is.null(theme)) {
12 0
    theme_dir = system.file('themes', package = 'knitr')
13 0
    theme_files = list.files(theme_dir,  pattern = '\\.css$')
14 0
    gsub('\\.css$', '', basename(theme_files))
15
  } else {
16 0
    theme_to_header(theme)
17
  }
18
}
19

20
#' Syntax highlighting themes
21
#'
22
#' This object can be used to set or get themes in \pkg{knitr} for syntax
23
#' highlighting.
24
#'
25
#' We can use \code{knit_theme$set(theme)} to set the theme, and
26
#' \code{knit_theme$get(theme)} to get a theme. The \code{theme} is a character
27
#' string for both methods (either the name of the theme, or the path to the CSS
28
#' file of a theme), and for the \code{set()} method, it can also be a list
29
#' returned by the \code{get()} method. See examples below.
30
#' @author Ramnath Vaidyanathan and Yihui Xie
31
#' @references For a preview of all themes, see
32
#'   \url{https://gist.github.com/yihui/3422133}.
33
#' @note The syntax highlighting here only applies to \file{.Rnw} (LaTeX) and
34
#'   \file{.Rhtml} (HTML) documents, and it does not work for other types of
35
#'   documents, such as \file{.Rmd} (R Markdown, which has its own syntax
36
#'   highlighting themes; see \url{https://rmarkdown.rstudio.com}).
37
#' @export
38
#' @examples opts_knit$set(out.format='latex'); knit_theme$set('edit-vim')
39
#'
40
#' knit_theme$get()  # names of all available themes
41
#'
42
#' thm = knit_theme$get('acid')  # parse the theme to a list
43
#' knit_theme$set(thm)
44
#'
45
#' opts_knit$set(out.format=NULL) # restore option
46
knit_theme = list(set = set_theme, get = get_theme)
47

48

49
#' Generates header based on a theme and output format of document
50
#' @author Ramnath Vaidyanathan
51
#' @noRd
52
theme_to_header = function(theme, format = out_format()){
53 1
  if (format == 'latex') {
54 1
    theme_to_header_latex(theme)
55 1
  } else theme_to_header_html(theme)
56
}
57

58
#' Generates latex header based on a theme
59
#' @author Ramnath Vaidyanathan
60
#' @noRd
61
theme_to_header_latex = function(theme) {
62 1
  css_file = if (file.exists(theme)) theme else {
63 1
    system.file('themes', sprintf('%s.css', theme), package = 'knitr', mustWork = TRUE)
64
  }
65 1
  css_out = css.parser(css_file)
66

67
  # get background and foreground colors
68 1
  background = css_out$background$color
69 1
  foreground = css_out$std$color
70

71
  # write latex highlight header
72 1
  fgheader = color_def(foreground, 'fgcolor')
73 1
  highlight = one_string(c(fgheader, styler_assistant_latex(css_out[-1])))
74 1
  list(highlight = highlight, background = background, foreground = foreground)
75
}
76

77
#' Generates css header based on a theme
78
#' @author Ramnath Vaidyanathan
79
#' @noRd
80
theme_to_header_html = function(theme){
81 1
  css_file = if (file.exists(theme)) theme else {
82 1
    system.file('themes', sprintf('%s.css', theme), package = 'knitr')
83
  }
84 1
  css = css.parser(css_file)
85 1
  bgcolor = css$background$color
86 1
  css_knitr = read_utf8(system.file('misc', 'knitr.css', package = 'knitr'))
87 1
  css_knitr[-2] = sub('^(\\s+background-color:\\s+)(.*)$', sprintf('\\1%s;', bgcolor), css_knitr[-2])
88 1
  css = c(css_knitr, gsub('^([.][a-z]{3} )', '.hl\\1', read_utf8(css_file)[-(1:3)]))
89 1
  list(highlight = one_string(css))
90
}
91

92
# parse a theme file from Highlight v3.x by Andre Simon to an R list of the form
93
# list(Colour = hex, Bold = TRUE, Italic = TRUE)
94
theme2list = function(theme.file) {
95 1
  y = read_utf8(theme.file)
96 1
  i = grep('^\\s*Description', y)
97 1
  if (i > 1) y = y[-seq_len(i - 1)]
98 1
  y = gsub('[{]', 'list(', y)
99 1
  y = gsub('[}]', ')', y)
100 1
  y = gsub(';', '', y)
101 1
  y = gsub('true', 'TRUE', y)
102 1
  y = one_string(y)
103 1
  y = gsub(',\\s*)', ')', y)
104 1
  env = new.env()
105
  #cat(y, sep = '\n')
106 1
  eval(parse(text = y), envir = env)
107 1
  y = as.list(env)
108 1
  for (i in seq_along(y$Keywords)) {
109 1
    y[[paste0('Keyword', i)]] = y$Keywords[[i]]
110
  }
111 1
  y$Keywords = NULL
112 1
  y
113
}
114

115
# mapping between CSS class and Highlight theme elements
116
cls2thm = c(
117
  background = 'Canvas', num = 'Number', str = 'String', com = 'BlockComment',
118
  opt = 'Operator', std = 'Default',
119
  kwa = 'Keyword1', kwb = 'Keyword2', kwc = 'Keyword3', kwd = 'Keyword4'
120
)
121

122
# turn a list from theme2list() to CSS code
123
list2css = function(lst) {
124 1
  css = character(length(cls2thm))
125 1
  for (i in seq_along(cls2thm)) {
126 1
    m = cls2thm[i]; l = lst[[m]]
127
    # if not found, use the default style
128 0
    if (!is.list(l)) l = lst[['Default']]
129 1
    css[i] = one_string(c(
130 1
      sprintf('.%s {', names(m)), sprintf('  color: %s;', l$Colour),
131 1
      sprintf('  font-weight: %s;', if (isTRUE(l$Bold)) 'bold'),
132 1
      sprintf('  font-style: %s;', if (isTRUE(l$Italic)) 'italic'), '}'
133
    ))
134
  }
135 1
  css
136
}
137

138
# generate CSS files for all themes in Andre Simon's Highlight package, e.g.
139
# themes2css('~/tmp/highlight/themes', '~/downloads/knitr/inst/themes')
140
themes2css = function(theme.path, css.path) {
141 1
  for (f in list.files(theme.path, pattern = '[.]theme$', full.names = TRUE)) {
142 1
    theme.name = sub('[.]theme$', '', basename(f))
143 1
    css.file = file.path(css.path, sprintf('%s.css', theme.name))
144 1
    write_utf8(list2css(theme2list(f)), css.file)
145 1
    message('theme ', theme.name, ' saved to ', css.file)
146
  }
147
}

Read our documentation on viewing source code .

Loading