S4 objects that expose the formatting controls for
objects. Many predefined formats are defined as classes that extend the
Style class. You may fine tune styles by either extending
the pre-defined classes, or modifying an instance thereof.
TRUE or FALSE, whether the text should be hard wrapped to fit in the console
TRUE or FALSE, whether text should be right padded
what type of
what character value to substitute for NA elements; NA elements are generated when lining up side by side diffs by adding padding rows; by default the text styles replace these with a blank character string, and the HTML styles leave them as NA for the HTML formatting functions to deal with
sub what character value to replace blanks with; needed in
particular for HTML rendering (uses
function that accepts at least two parameters and requires
no more than two parameters, will receive as the first parameter the
the object to render (either a
Style S4 object
Pre-defined classes are used to populate the
object, which in turn allows the
diff* methods to pick the
Style for each combination of the
brightness parameters when the
parameter is set to “auto”. The following classes are pre-defined:
StyleRaw: No styles applied
Each of these classes has an associated constructor function with the
same name (see examples). Objects instantiated from these classes
may also be used directly as the value for the
style parameter to the
diff* methods. This will override the automatic selection process
PaletteOfStyles. If you wish to tweak an
auto-selected style rather than explicitly specify one, pass a parameter
list instead of a
Style objects as the
style parameter to the
diff* methods (see examples).
There are predefined classes for most combinations of
format/color.mode/brightness, but not all. For example, there are
brightness defined for the “html”
format, and those classes are re-used for all possible
brightness values, and the 8 color ANSI neutral classes are used
for the 256 color neutral selections as well.
To get a preview of what a style looks like just instantiate
an object; the
show method will output a trivial diff to screen with
styles applied. Note that for ANSI styles of the dark and light variety
the show method colors the terminal background and foregrounds in compatible
colors. In normal usage the terminal background and foreground colors are
left untouched so you should not expect light styles to look good on dark
background and vice versa even if they render correctly when showing the
Most of the customization is done by specifying functions that operate on
character vectors and return a modified character vector of the same length.
The intended use case is to pass
crayon functions such as
crayon::red, although you may pass any function of your liking
that behaves as described. Formatting functions are expected to return their
inputs formatted in such a way that their display width is unchanged.
If your formatting functions change display width output may not render
properly, particularly when using
The visual representation of the diff has many nested components. The functions you specify here will be applied starting with the innermost ones. A schematic of the various component that represent an inserted line follows (note “insert” abbreviated to “ins”, and “gutter” abbreviated to “gtr”):
1 2 3 4 5 6 7 8 9 10 11
+- line ---------------------------------------------------+ |+- line.ins ---------------------------------------------+| ||+- gtr ------------------------++- text ---------------+|| |||+- gtr.ins ---++- gtr.pad ---+||+- text.ins ---------+||| |||| || |||| +- word.ins -+|||| |||| gtr.ins.txt || gtr.pad.txt |||| DIFF | TEXT HERE ||||| |||| || |||| +------------+|||| |||+-------------++-------------+||+--------------------+||| ||+------------------------------++----------------------+|| |+--------------------------------------------------------+| +----------------------------------------------------------+
A similar model applies to deleted and matching lines. The boxes represent
gutter.insert.txt represents the text to use in the gutter
and is not a function.
DIFF TEXT HERE is text from the objects being
diffed, with the portion that has different words inside the
gutter.pad.txt are used to
separate the gutter from the text and usually end up resolving to a space.
Most of the functions defined here default to
you are given the flexibility to fully format the diff. See
StyleText for a full listing of
the adjustable elements.
In side-by-side mode there are two “lines” per screen line, each with the structure described here.
The structure described here may change in the future.
If you use a
Style that inherits from
diff will be wrapped in HTML tags, styled with CSS, and output to
getOption("viewer") if your IDE supports it (e.g. Rstudio), or
directly to the browser otherwise, assuming that the default
Pager or a correctly configured pager that inherits from
PagerBrowser is in effect. Otherwise, the raw HTML will be
output to your terminal.
By default HTML output sent to the viewer/browser is a full stand-alone
webpage with CSS styles to format and color the diff, and JS code to
handle scaling. The CSS and JS is read from the
default files and injected into the HTML to simplify
packaging of the output. You can customize the CSS and JS by using the
js arguments respectively, but read the rest of this
documentation section if you plan on doing so.
Should you want to capture the HTML output for use elsewhere, you can do
so by using
as.character on the return value of the
methods. If you want the raw HTML without any of the headers, CSS, and
html.ouput="diff.only" when you instantiate the
StyleHtml object (see examples), or disable the
Another option is
html.output="diff.w.style" which will add
<style> tags with the CSS, but without wrapping those in
tags. This last option results in illegal HTML with a
outside of the
<head> block, but appears to work and is useful if you
want to embed HTML someplace but do not have access to the headers.
If you wish to modify the CSS styles you should do so cautiously. The
HTML and CSS work well together out of the box, but may not take to kindly
to modifications. The safest changes you can make are to the colors of the
scheme. You also probably should not modify the functions in the
@funs slot of the
StyleHtml object. If you want to provide
your own custom styles make a copy of the file at the location returned by
diffobj_css(), modify it to your liking, and pass the location of your
modified sheet back via the
css argument (see examples).
in the viewport. If you wish to turn of this behavior you can do so via the
@funs functions, but otherwise you are probably best off leaving
Both the CSS and JS files can be specified via options, “diffobj.html.css”, and “diffobj.html.js” respectively.
If you define your own custom
StyleHtml object you may want to modify
@funs@container. This slot contains a function that is
applied to the entire diff output. For example,
@funs@container <- cont_f("light", "rgb").
a function that accepts a character vector as an argument and returns
that value wrapped in a
DIV block with class
“"diffobj_container light rgb"”. This allows the CSS style sheet to
Diff elements with the correct styles.
Often you will want to specify some of the style parameters (e.g.
scale for html styles) while still relying on the default style
selection to pick the specific style. You can do so by passing a list to the
style parameter of the
You can in theory create entirely new classes that extent
example you could generate a class that renders the diff in
graphics. Note however that we have not tested such extensions and it is
possible there is some embedded code that will misbehave with such a new
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
## Not run: ## Create a new style based on existing style by changing ## gutter symbols and guide color; see `?StyleFuns` and ## `?StyleText` for a full list of adjustable elements my.style <- StyleAnsi8NeutralYb() my.style ## `show` method gives you a preview of the style my.style@email@example.com <- "+++" my.style@firstname.lastname@example.org <- "---" my.style@email@example.com <- crayon::green my.style ## Notice gutters and guide color ## Provide a custom style sheet; here we assume there is a style sheet at ## `HOME/web/mycss.css` my.css <- file.path(path.expand("~"), "web", "mycss.css") diffPrint(1:5, 2:6, style=StyleHtmlLightYb(css=my.css)) ## Turn of scaling; notice how we pass a list to `style` ## and we do not need to specify a specific style diffPrint(letters, letters[-5], format="html", style=list(scale=FALSE)) ## Alternatively we can do the same by specifying a style, but we must ## give an exact html style instead of relying on preferences to pick ## one for us my.style <- StyleHtmlLightYb(scale=FALSE) diffPrint(letters, letters[-5], style=my.style) ## End(Not run) ## Return only the raw HTML without any of the headers as.character( diffPrint(1:5, 2:6, format="html", style=list(html.output="diff.only")) )