├── .editorconfig ├── .eslintrc.json ├── .gitattributes ├── .gitignore ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── grammars ├── context.cson ├── desc.cson ├── ditroff.cson ├── gremlin.cson ├── ideal.cson ├── manref.cson ├── pic.cson ├── roff.cson └── runoff.cson ├── index.js ├── keymaps └── keys.cson ├── lib ├── conversion.js ├── editing.js ├── hyperlinks.js ├── previewing.js ├── utils.js └── views │ ├── template.html │ └── troff-view.js ├── menus └── roff.cson ├── package.json ├── settings └── editor.cson ├── snippets └── snippets.cson ├── spec ├── .mocharc.js ├── fixtures │ ├── input │ │ ├── art-1.pic │ │ ├── art-2.pic │ │ ├── art-3.pic │ │ ├── art.pikchr │ │ ├── colours.pikchr │ │ ├── context.sqtroff │ │ ├── ditroff.1 │ │ ├── ditroff.2 │ │ ├── ditroff.3 │ │ ├── do.roff │ │ ├── escapes.roff │ │ ├── font-BI.1 │ │ ├── font-BI.2 │ │ ├── font-BI.3 │ │ ├── font-BR.1 │ │ ├── font-BR.2 │ │ ├── font-BR.3 │ │ ├── font-IB.1 │ │ ├── font-IB.2 │ │ ├── font-IB.3 │ │ ├── font-IR.1 │ │ ├── font-IR.2 │ │ ├── font-IR.3 │ │ ├── font-RB.1 │ │ ├── font-RB.2 │ │ ├── font-RB.3 │ │ ├── font-RI.1 │ │ ├── font-RI.2 │ │ ├── font-RI.3 │ │ └── links.1 │ ├── output │ │ ├── art-1.pic.json │ │ ├── art-2.pic.json │ │ ├── art-3.pic.json │ │ ├── art.pikchr.json │ │ ├── colours.pikchr.json │ │ ├── ditroff.1.json │ │ ├── ditroff.2.json │ │ ├── ditroff.3.json │ │ ├── do.roff.json │ │ ├── escapes.roff.json │ │ ├── font-BI.1.json │ │ ├── font-BI.2.json │ │ ├── font-BI.3.json │ │ ├── font-BR.1.json │ │ ├── font-BR.2.json │ │ ├── font-BR.3.json │ │ ├── font-IB.1.json │ │ ├── font-IB.2.json │ │ ├── font-IB.3.json │ │ ├── font-IR.1.json │ │ ├── font-IR.2.json │ │ ├── font-IR.3.json │ │ ├── font-RB.1.json │ │ ├── font-RB.2.json │ │ ├── font-RB.3.json │ │ ├── font-RI.1.json │ │ ├── font-RI.2.json │ │ ├── font-RI.3.json │ │ └── links.1.json │ ├── prune │ └── update └── grammar-spec.js └── styles └── styles.less /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | trim_trailing_whitespace = false 8 | indent_style = tab 9 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@alhadis/eslint-config/atom", 3 | "rules": { 4 | "require-atomic-updates": 0 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pikchr linguist-language=Pic 2 | 3 | # GitHub doesn't support these formats, so we abuse its language 4 | # classification system in the name of superior highlighting. 5 | *.ditroff linguist-language=Roff 6 | *.sqtroff linguist-language=Roff 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Mac OS/X 2 | .apdisk 3 | .AppleDB 4 | .AppleDesktop 5 | .AppleDouble 6 | .DS_Store 7 | .LSOverride 8 | ._* 9 | 10 | 11 | ## IDE-specific 12 | sftp-config.json 13 | .project 14 | 15 | 16 | ## Windows 17 | Desktop.ini 18 | Thumbs.db 19 | ehthumbs.db 20 | $RECYCLE.BIN/ 21 | *.lnk 22 | 23 | 24 | ## Other 25 | error_log 26 | node_modules 27 | components 28 | npm-debug.log 29 | .apl.history 30 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Change Log 2 | ========== 3 | 4 | This project adheres to [Semantic Versioning](http://semver.org). 5 | 6 | 7 | [Staged] 8 | ------------------------------------------------------------------------ 9 | * __Added:__ Support for SoftQuad Context (SQTroff intermediate output) 10 | * __Added:__ Highlighting for variable-length point-size adjustments 11 | * __Added:__ Highlighting for [OSC 8] terminal hyperlink device controls 12 | * __Added:__ Highlighting for [dpic] and [Pikchr] language extensions 13 | * __Added:__ Highlighting for new requests added in [Groff v1.23.0][2] 14 | * __Added:__ Embedded shell highlighting to `.pi`, `.pso`, and `.sy` 15 | * __Changed:__ `.device` requests now highlight device control functions 16 | * __Changed:__ Man page references now exclude leading `man:` prefixes 17 | * __Changed:__ Texinfo documents now exempted from man page hyperlinking 18 | * __Fixed:__ `{` not expanding into `\{\ … .\}` inside `.while` requests 19 | * __Fixed:__ Inconsistent command highlighting in `.do` requests 20 | * __Fixed:__ Highlighting of `\s(±NN` inconsistent with `\s±(NN` 21 | * __Fixed:__ Conditional requests not highlighting the commands they run 22 | * __Fixed:__ Parameter highlighting terminated at the letter `R` in Atom 23 | * __Fixed:__ refer(1)-like markup inside macro definitions now truncated 24 | * __Fixed:__ Various [inaccuracies][1] related to Roff modeline matching 25 | * __Improved:__ Handling of postprocessor input misclassified as Roff 26 | * __Improved:__ Colour of ASCII control characters in dark themes 27 | * __Improved:__ Accuracy and granularity of Pic highlighting 28 | 29 | [1]: https://github.com/github/linguist/pull/5271 30 | [2]: http://git.savannah.gnu.org/cgit/groff.git/tree/NEWS?id=888464a#n10 31 | [dpic]: https://gitlab.com/aplevich/dpic 32 | [OSC 8]: https://lists.gnu.org/archive/html/groff/2021-10/msg00000.html 33 | [pikchr]: https://pikchr.org/home/doc/trunk/doc/differences.md 34 | 35 | 36 | [v1.3.1] 37 | ------------------------------------------------------------------------ 38 | **October 16th, 2020** 39 | * __Added:__ Editor command for evaluating selection with `groff -Tutf8` 40 | * __Added:__ `mdoc.template` and `man.template` as recognised Roff files 41 | * __Added:__ Recognition of `.\"`, `.Dt/.Dd` and `$Mdocdate$` in headers 42 | * __Added:__ Support for `.ditroff` files containing intermediate output 43 | * __Added:__ Highlighting of certain [C0 control codes][] in identifiers 44 | * __Added:__ Highlighting for new `.stringdown` and `.stringup` requests 45 | * __Added:__ Highlighting for Heirloom's `\U`, `\T`, and `\W` extensions 46 | * __Added:__ Highlighting for device control functions 47 | * __Changed:__ `Dt` and `Sh` macros now highlighted like `TH` and `SH` 48 | * __Changed:__ Enabled soft-wrapping in Roff documents by default 49 | * __Changed:__ `.while` requests now highlighted the same as `.if`/`.ie` 50 | * __Fixed:__ `ditroff(7)` commands only tokenised at the start of a line 51 | * __Fixed:__ Incorrect highlighting of man page links containing colons 52 | * __Fixed:__ Missing highlighting of escape sequences in some contexts 53 | * __Improved:__ Highlighting of `.Dd` macros and `$Mdocdate$` constructs 54 | 55 | 56 | [v1.3.0] 57 | ------------------------------------------------------------------------ 58 | **December 31st, 2019** 59 | * __Added:__ Automatic expansion of `{` into `\{\ … .\}` in conditionals 60 | * __Added:__ Automatic suppression of closing quotes and parentheses 61 | * __Added:__ Editor command to replace blank lines in Roff documents 62 | * __Added:__ Highlighting for `gperl`, `glilypond`, and `gpinyin` macros 63 | * __Added:__ Highlighting for shell source embedded with `mdoc`'s `.Bd` 64 | * __Added:__ Man-page previewer and clickable page hyperlinks 65 | * __Added:__ Missing highlighting for numerous `\f` sequences 66 | * __Added:__ Snippet for inserting a bordered section heading 67 | * __Added:__ Support for sequences escaped by Groff's `\E` 68 | * __Added:__ Vastly improved highlighting for `eqn` and `grn` markup 69 | * __Fixed:__ Conversion commands not working for opened `.pic` files 70 | * __Fixed:__ Documents mangled when rendering preprocessed Pic output 71 | * __Fixed:__ Escape sequences not highlighted in register definitions 72 | * __Fixed:__ Highlighting for `\f` escapes not terminated correctly 73 | * __Fixed:__ User-defined character names not highlighted by `\(xx` 74 | * __Fixed:__ Macros starting with `.[` always assumed to be `refer(1)` 75 | * __Fixed:__ Macros starting with `cu-` mistaken for `.cu` requests 76 | * __Fixed:__ Snippets not working when hitting tab key 77 | * __Improved:__ Highlighting of arithmetic and comparison operators 78 | * __Removed:__ `.t` from associated file extensions 79 | 80 | 81 | [v1.2.2] 82 | ------------------------------------------------------------------------ 83 | **February 26th, 2017** 84 | * __Added:__ Commands for converting Roff to other document formats 85 | * __Added:__ Highlighting for intermediate output and font descriptions 86 | * __Added:__ Intelligent indentation of control lines 87 | * __Added:__ Various obscure extensions to supported filetypes 88 | * __Fixed:__ Bugs with matching certain Vim/Emacs modelines 89 | * __Fixed:__ RUNOFF literal blocks not terminated at `.end lit` 90 | * __Fixed:__ Underline missing after `.cu` requests 91 | * __Fixed:__ Various bugs with highlighting escapes and Pic commands 92 | 93 | 94 | [v1.2.1] 95 | ------------------------------------------------------------------------ 96 | **August 1st, 2016** 97 | Patch for several highlighting-related bugs. 98 | 99 | * __Added:__ Snippet for inserting 3-column table 100 | * __Fixed:__ Comments not highlighted without preceding whitespace 101 | * __Fixed:__ Escape sequences not detected inside GNU long-names 102 | * __Fixed:__ Escape sequences not recognised in string definitions 103 | * __Fixed:__ Inconsistent highlighting applied to interpolated arguments 104 | * __Fixed:__ Macros matched as substrings of longer names 105 | * __Fixed:__ String definitions unable to span multiple lines 106 | * __Improved:__ Handling of requests without whitespace 107 | 108 | 109 | [v1.2.0] 110 | ------------------------------------------------------------------------ 111 | **July 29th, 2016** 112 | Support for Troff preprocessors and the venerable RUNOFF has been added, 113 | along with numerous other enhancements. 114 | 115 | * __Added:__ Full syntax highlighting for `mdoc` macros 116 | * __Added:__ Language support for RUNOFF 117 | * __Added:__ Missing support for GNU-style long-names (`\*[name]`) 118 | * __Added:__ Snippets for conditionals, definitions, and page templates 119 | * __Added:__ Support for chem, dformat, eqn, grap, pic, refer, and tbl 120 | * __Fixed:__ Alphabetic Vroff conditional not matched (`.if v`) 121 | * __Fixed:__ Decimals without leading digits not recognised 122 | * __Fixed:__ `.ig` macros not blanking out their contents 123 | * __Fixed:__ Point-size adjustments incorrectly highlighted 124 | 125 | 126 | [v1.1.0] 127 | ------------------------------------------------------------------------ 128 | **July 20th, 2016** 129 | This release addresses a number of glaring bugs with highlighting fonts, 130 | and improves the lexical accuracy of the grammar's pattern-matching. 131 | 132 | * __Added:__ Support for all Groff-related features and extensions 133 | * __Fixed:__ Blank elements not permitted in 3-part title strings 134 | * __Fixed:__ Control lines not matched after `\fB` and its ilk 135 | * __Fixed:__ Escape sequences formatted like ordinary markup 136 | * __Fixed:__ Paragraph macros not resetting bold/italic formatting 137 | * __Fixed:__ Various edge cases with oddly-formed syntax 138 | * __Improved:__ Highlighting of escape sequences and generic macros 139 | 140 | 141 | [v1.0.0] 142 | ------------------------------------------------------------------------ 143 | **July 17th, 2016** 144 | Initial release. Adds syntax highlighting and language support for Roff. 145 | 146 | 147 | [Referenced links]:_____________________________________________________ 148 | [C0 control codes]: http://en.wikipedia.org/wiki/C0_and_C1_control_codes 149 | [Staged]: https://github.com/Alhadis/language-roff/compare/v1.3.1...HEAD 150 | [v1.3.1]: https://github.com/Alhadis/language-roff/releases/tag/v1.3.1 151 | [v1.3.0]: https://github.com/Alhadis/language-roff/releases/tag/v1.3.0 152 | [v1.2.2]: https://github.com/Alhadis/language-roff/releases/tag/v1.2.2 153 | [v1.2.1]: https://github.com/Alhadis/language-roff/releases/tag/v1.2.1 154 | [v1.2.0]: https://github.com/Alhadis/language-roff/releases/tag/v1.2.0 155 | [v1.1.0]: https://github.com/Alhadis/language-roff/releases/tag/v1.1.0 156 | [v1.0.0]: https://github.com/Alhadis/language-roff/releases/tag/v1.0.0 157 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016-2024, John Gardner 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Roff Language Support 2 | ===================== 3 | 4 | Support for Unix manual pages (Troff/Groff) in Atom, as well as the entire Roff typesetting language. 5 | 6 | ![What? Nobody writes this by hand anymore?](https://raw.githubusercontent.com/Alhadis/language-roff/02696cdbcca95d7d478ccf703bc22fbe27da48c7/figure-1.png) 7 | 8 | See [**roff**(7)](https://man7.org/linux/man-pages/man7/roff.7.html) or [*"History of UNIX Manpages"*](http://manpages.bsd.lv/history.html) for a comprehensive rundown of the language's history. 9 | 10 | 11 | Coverage 12 | -------- 13 | * Every macro package: [`man`], [`mdoc`], [`me`], [`ms`], [`mm`], [`mom`], [`www`] 14 | * Every preprocessor: [`chem`], [`dformat`], [`eqn`], [`grap`], [`ideal`], [`pic`], [`refer`], [`tbl`] 15 | * GNU Troff extensions 16 | * The ancient [RUNOFF] language, with support for [OpenVMS DSR] 17 | * Intermediate representations: [`ditroff`], SoftQuad Context 18 | 19 | 20 | [`man`]: https://man7.org/linux/man-pages/man7/groff_man.7.html 21 | [`mdoc`]: https://man.openbsd.org/mdoc.7 22 | [`me`]: https://man7.org/linux/man-pages/man7/groff_me.7.html 23 | [`ms`]: https://man7.org/linux/man-pages/man7/groff_ms.7.html 24 | [`mm`]: https://man7.org/linux/man-pages/man7/groff_mm.7.html 25 | [`mom`]: http://www.schaffter.ca/mom/ 26 | [`www`]: https://man7.org/linux/man-pages/man7/groff_www.7.html 27 | [`chem`]: https://man7.org/linux/man-pages/man1/chem.1.html 28 | [`dformat`]: https://rbn.im/bell-labs/cm.bell-labs.com/cm/cs/cstr/142.ps.gz 29 | [`eqn`]: https://en.wikipedia.org/wiki/Eqn 30 | [`grap`]: https://rbn.im/bell-labs/cm.bell-labs.com/cm/cs/cstr/114.ps.gz 31 | [`ideal`]: http://man.cat-v.org/unix_8th/1/ideal 32 | [`pic`]: https://en.wikipedia.org/wiki/Pic_language 33 | [`refer`]: https://en.wikipedia.org/wiki/Refer_(software) 34 | [`tbl`]: https://en.wikipedia.org/wiki/Tbl 35 | [`ditroff`]: https://man7.org/linux/man-pages/man7/ditroff.7.html 36 | [RUNOFF]: https://github.com/bwarken/RUNOFF_historical/ 37 | [OpenVMS DSR]: http://h20565.www2.hpe.com/hpsc/doc/public/display?docId=emr_na-c04623260 38 | -------------------------------------------------------------------------------- /grammars/desc.cson: -------------------------------------------------------------------------------- 1 | name: "Roff (Device Description)" 2 | scopeName: "source.ditroff.desc" 3 | fileTypes: [ 4 | "DESC" 5 | "DESC.big" 6 | "DESC.small" 7 | "DESC.in" 8 | "DESC.proto" 9 | "DESC.8400" 10 | "R.proto" 11 | "tab.37" 12 | "tab.450" 13 | "tab.450-12" 14 | "tab.lp" 15 | "tab.think" 16 | "text.enc" 17 | "devps/download" 18 | "devpdf/download" 19 | "devpdf/Foundry" 20 | ] 21 | firstLineMatch: "# This file has been generated with GNU afmtodit" 22 | patterns: [{ 23 | # Modified pattern-set for obvious device-description files 24 | begin: "(?=^\\s*(?:fonts|res|hor|vert|unitwidth|biggestfont)(?:\\s|$))" 25 | end: "(?=A)B" 26 | patterns: [{ 27 | name: "meta.charset.ditroff.desc" 28 | begin: "^(charset)\\s*$" 29 | end: "(?=A)B" 30 | beginCaptures: 31 | 1: name: "keyword.control.section.ditroff.desc" 32 | patterns: [ 33 | {include: "#comment"} 34 | {match: "\\S+", name: "entity.name.glyph.ditroff.desc"} 35 | ] 36 | }, include: "#main"] 37 | }, include: "#main"] 38 | 39 | repository: 40 | main: 41 | patterns: [ 42 | {include: "#foundry"} 43 | {include: "#comment"} 44 | {include: "#charset"} 45 | {include: "#fields"} 46 | {include: "#kernpairs"} 47 | {include: "#fontPath"} 48 | ] 49 | 50 | charset: 51 | name: "meta.charset.ditroff.desc" 52 | begin: "^(charset)\\s*$" 53 | end: "^(?=kernpairs|\\s*$)" 54 | beginCaptures: 55 | 1: name: "keyword.control.section.ditroff.desc" 56 | patterns: [{ 57 | name: "meta.glyph.ditroff.desc" 58 | match: """(?x) ^ 59 | \\s* ((---)|\\S+) # Name 60 | \\s+ ([-\\d]+(?:,[-\\d]+){0,5}) # Metrics 61 | \\s+ (\\d) # Glyph type 62 | \\s+ (0[Xx][0-9A-Fa-f]+|\\d+) # Code 63 | (?:\\s+(?!--)(\\S+))? # Entity name 64 | """ 65 | captures: 66 | 1: name: "entity.name.glyph.ditroff.desc" 67 | 2: name: "punctuation.definition.unnamed.glyph.ditroff.desc" 68 | 3: patterns: [ 69 | {match: "-?\\d+", name: "constant.numeric.integer.ditroff.desc"} 70 | {match: ",", name: "punctuation.delimiter.comma.ditroff.desc"} 71 | ] 72 | 4: name: "constant.numeric.integer.ditroff.desc" 73 | 5: name: "constant.numeric.integer.ditroff.desc" 74 | 6: name: "variable.other.ditroff.desc" 75 | },{ 76 | name: "meta.glyph.alias.ditroff.desc" 77 | match: "^\\s*(\\S+)\\s+(\")(?=\\s|$)" 78 | captures: 79 | 1: name: "entity.type.var.ditroff.desc" 80 | 2: name: "keyword.operator.ditroff.desc" 81 | },{ 82 | name: "comment.line.double-dash.ditroff.desc" 83 | begin: "(?<=\\s)--(?!-)" 84 | end: "(?=$)" 85 | beginCaptures: 86 | 0: name: "punctuation.definition.comment.ditroff.desc" 87 | }, include: "#comment"] 88 | 89 | comment: 90 | name: "comment.line.number-sign.ditroff.desc" 91 | begin: "#" 92 | end: "$" 93 | beginCaptures: 94 | 0: name: "punctuation.definition.comment.ditroff.desc" 95 | 96 | fields: 97 | patterns: [{ 98 | name: "meta.$1-list.ditroff.desc" 99 | begin: "^\\s*(ligatures|sizes)(?=\\s)" 100 | end: "(?<=\\s)0(?=\\s*$)|(?=^(?!\\s*$)(?!\\s*[\\d#]))" 101 | beginCaptures: 102 | 1: name: "entity.type.var.ditroff.desc" 103 | endCaptures: 104 | 0: name: "punctuation.terminator.statement.ditroff.desc" 105 | patterns: [ 106 | name: "constant.numeric.range.ditroff.desc" 107 | match: "\\d+(-)\\d+" 108 | captures: 1: name: "punctuation.separator.range.dash.ditroff.desc" 109 | 110 | {include: "#comment"} 111 | {name: "constant.numeric.integer.desc", match: "\\d+"} 112 | {name: "variable.parameter.ditroff.desc", match: "\\S{2,}"} 113 | ] 114 | },{ 115 | name: "meta.papersize.ditroff.desc" 116 | begin: "^\\s*(papersize)(?=\\s)" 117 | end: "(?=$|#)" 118 | beginCaptures: 119 | 1: name: "entity.type.var.ditroff.desc" 120 | patterns: [include: "#paperSizes"] 121 | },{ 122 | begin: """(?x)^\\s* 123 | (afmfonts|allpunct|anysize|biggestfont|broken|checksum|designsize|encoding|family 124 | |fonts|hor|image_generator|internalname|lc_ctype|name|orientation|paper(?:length|width) 125 | |pass_filenames|postpro|prepro|print|res|sizescale|slant|spacewidth|spare\\d|special 126 | |styles|tcommand|unicode|unitwidth|unscaled_charwidths|use_charnames_in_special|vert 127 | |X11|(?:lbp|pcl)[a-z]+) 128 | (?=\\s)""" 129 | end: "(?=$|#)" 130 | beginCaptures: 131 | 1: name: "entity.type.var.ditroff.desc" 132 | patterns: [ 133 | {name: "constant.numeric.ditroff.desc", match: "-?[\\d.]+(?=\\s|$)"} 134 | {name: "variable.parameter.ditroff.desc", match: "\\S+"} 135 | ] 136 | }] 137 | 138 | 139 | fontPath: 140 | match: "^(?:(\\w+)?\\t+)?(\\S+)\\t+(\\*)?(\\S+(?:\\.pf[ab]|[\\/]Resource[\\/]Font[\\/]\\S+))\\s*$" 141 | captures: 142 | 1: name: "variable.other.foundry.ditroff.desc" 143 | 2: name: "entity.name.var.ditroff.desc" 144 | 3: name: "keyword.operator.globstar.ditroff.desc" 145 | 4: name: "string.quoted.double.filename.ditroff.desc" 146 | 147 | 148 | foundry: 149 | name: "meta.foundry-data.ditroff.desc" 150 | begin: "^(#)Foundry\\|Name\\|Searchpath\\s*$" 151 | end: "(?=A)B" 152 | beginCaptures: 153 | 0: name: "comment.line.number-sign.ditroff.desc" 154 | 1: name: "punctuation.definition.comment.ditroff.desc" 155 | patterns: [include: "#comment", { 156 | match: "^([^\\s|]+)(\\|)([YN])(\\|)([rins]+)?(\\|)(?:([.\\w]*)(\\|)([.\\w]*)(?=\\|))?" 157 | captures: 158 | 1: name: "entity.name.var.ditroff.desc" 159 | 2: name: "punctuation.delimiter.pipe.ditroff.desc" 160 | 3: name: "constant.boolean.is-base64.ditroff.desc" 161 | 4: name: "punctuation.delimiter.pipe.ditroff.desc" 162 | 5: name: "constant.language.flags.ditroff.desc" 163 | 6: name: "punctuation.delimiter.pipe.ditroff.desc" 164 | 7: name: "variable.parameter.ditroff.desc" 165 | 8: name: "punctuation.delimiter.pipe.ditroff.desc" 166 | 9: name: "variable.parameter.ditroff.desc" 167 | },{ 168 | match: "^(foundry)(\\|)(\\w*)(\\|)((\\()\\w+(\\)))?([^|#]+)" 169 | captures: 170 | 1: name: "storage.type.foundry.ditroff.desc" 171 | 2: name: "punctuation.delimiter.pipe.ditroff.desc" 172 | 3: name: "variable.other.foundry.ditroff.desc" 173 | 4: name: "punctuation.delimiter.pipe.ditroff.desc" 174 | 5: name: "string.interpolated.ditroff.desc" 175 | 6: name: "punctuation.definition.arguments.begin.ditroff.desc" 176 | 7: name: "punctuation.definition.arguments.end.ditroff.desc" 177 | 8: name: "string.quoted.double.filename.ditroff.desc", patterns: [ 178 | match: ":", name: "punctuation.separator.key-value.colon.ditroff.desc" 179 | ] 180 | },{ 181 | name: "meta.foundry-font.ditroff.desc" 182 | match: "(?<=\\|)(?:([^|!]+\\.pf[ab])|([^|!]+)(!)([^|!]+\\.pf[ab]))$" 183 | captures: 184 | 1: name: "string.quoted.double.filename.ditroff.desc" 185 | 2: name: "variable.parameter.ditroff.desc" 186 | 3: name: "punctuation.separator.fontname.ditroff.desc" 187 | 4: name: "string.quoted.double.filename.ditroff.desc" 188 | },{ 189 | name: "meta.afmtodit-flag.ditroff.desc" 190 | match: "^([a-z])(=)(?=-)([^#]+)(?=$|#)" 191 | captures: 192 | 1: name: "variable.other.ditroff.desc" 193 | 2: name: "keyword.operator.assignment.ditroff.desc" 194 | 3: name: "constant.other.ditroff.desc" 195 | }, match: "\\|", name: "punctuation.delimiter.pipe.ditroff.desc"] 196 | 197 | kernpairs: 198 | name: "meta.kernpairs.ditroff.desc" 199 | begin: "^(kernpairs)\\s*$" 200 | end: "^(?=charset|\\s*$)" 201 | beginCaptures: 202 | 1: name: "keyword.control.section.ditroff.desc" 203 | patterns: [{ 204 | name: "meta.kerning-pair.ditroff.desc" 205 | match: "^\\s*(\\S+)\\s+(\\S+)\\s+(-?\\d+)" 206 | captures: 207 | 1: name: "entity.name.var.ditroff.desc" 208 | 2: name: "entity.name.var.ditroff.desc" 209 | 3: name: "constant.numeric.integer.ditroff.desc" 210 | }] 211 | 212 | 213 | paperSizes: 214 | patterns: [{ 215 | name: "support.constant.papersize.ditroff.desc" 216 | match: "(?i)(?:[A-D][0-7]|DL|letter|legal|tabloid|ledger|statement|executive|com10|monarch)(?=$|[\\s#])" 217 | },{ 218 | name: "meta.custom-papersize.ditroff.desc" 219 | match: "(?<=\\s)([\\d.]+)([icpP])(,)([\\d.]+)([icpP])(?=\\s|$)" 220 | captures: 221 | 1: name: "constant.numeric.ditroff.desc" 222 | 2: name: "keyword.other.unit.ditroff.desc" 223 | 3: name: "punctuation.delimiter.comma.ditroff.desc" 224 | 4: name: "constant.numeric.ditroff.desc" 225 | 5: name: "keyword.other.unit.ditroff.desc" 226 | }] 227 | -------------------------------------------------------------------------------- /grammars/gremlin.cson: -------------------------------------------------------------------------------- 1 | name: "Gremlin Image" 2 | scopeName: "source.gremlin" 3 | fileTypes: [ 4 | "gsrc" 5 | "grn" 6 | "gremlin" 7 | ] 8 | firstLineMatch: "^\\s*(?:sun)?gremlinfile(?=\\s|$)" 9 | patterns: [ 10 | {include: "#data"} 11 | {include: "#tags"} 12 | ] 13 | 14 | repository: 15 | 16 | # .GS/.GE: Tags for embedding gremlin pictures 17 | tags: 18 | begin: "^([.'])[ \\t]*(GS)(?=$|\\s|\\\\E?[\"#])(.*)$" 19 | end: "^([.'])[ \\t]*(GE|GF)(?=$|\\s|\\\\E?[\"#])" 20 | beginCaptures: 21 | 0: name: "meta.function.begin.gremlin.macro.roff" 22 | 1: name: "punctuation.definition.macro.roff" 23 | 2: name: "entity.function.name.roff" 24 | 3: patterns: [{ 25 | name: "constant.language.alignment-mode.grn.roff" 26 | match: "(?:^|\\G)\\s*([LIC])\\b" 27 | }, include: "text.roff#escapes"] 28 | endCaptures: 29 | 0: name: "meta.function.end.gremlin.macro.roff" 30 | 1: name: "punctuation.definition.macro.roff" 31 | 2: name: "entity.name.function.roff" 32 | patterns: [{ 33 | begin: "\\A\\s*((?:sun)?gremlinfile)(?=\\s|$)" 34 | end: "(?=A)B" 35 | patterns: [include: "#data"] 36 | }, include: "#grn"] 37 | 38 | 39 | # grn(1) preprocessor commands 40 | grn: 41 | patterns: [{ 42 | # Boolean-type parameter 43 | name: "meta.directive.preprocessor.grn.roff" 44 | match: """(?ix) ^\\s* 45 | (pointscale|pointscal|pointsca|pointsc|points 46 | |point|poin|poi|po|p) (?:\\s+(on|off))? 47 | (?=\\s|$) """ 48 | captures: 49 | 1: name: "keyword.operator.point-scale.grn.roff" 50 | 2: name: "constant.language.boolean.grn.roff" 51 | },{ 52 | # Load gremlin data from file "XX" 53 | name: "meta.directive.preprocessor.grn.roff" 54 | match: "(?i)^\\s*(file|fil|fi|f)\\s+(\\S.*)" 55 | captures: 56 | 1: name: "keyword.control.directive.include.grn.roff" 57 | 2: name: "string.unquoted.filename.grn.roff" 58 | },{ 59 | # Everything else expected between .GS/.GE tags 60 | name: "keyword.operator.directive.preprocessor.grn.roff" 61 | match: """(?ix) ^\\s* 62 | ( [1-4] (?=\\s+\\S) 63 | | roman|roma|rom|ro|r 64 | | italics|italic|itali|ital|ita|it|i 65 | | bold|bol|bo|b 66 | | special|specia|speci|spec|spe|sp 67 | | stipple|stippl|stipp|stip|sti|st|l 68 | | scale|scal|sca|sc|x 69 | | narrow|narro|narr|nar|na 70 | | medium|mediu|medi|med|me 71 | | thick|thic|thi|th|t 72 | | default|defaul|defau|defa|def|de|d 73 | | width|widt|wid|wi|w 74 | | height|heigh|heig|hei|he|h 75 | ) (?=\\s|$)""" 76 | }, include: "text.roff#params"] 77 | 78 | 79 | # Actual image coordinates 80 | data: 81 | begin: "^\\s*((?:sun)?gremlinfile)(?=\\s|$).*" 82 | end: "^\\s*(-1)\\s*$" 83 | beginCaptures: 84 | 0: name: "meta.file.start.gremlin" 85 | 1: name: "keyword.control.flow.begin-file.gremlin" 86 | endCaptures: 87 | 0: name: "meta.file.end.gremlin" 88 | 1: name: "comment.line.ignored.end-of-file.gremlin" 89 | contentName: "meta.file.body.gremlin" 90 | patterns: [{ 91 | name: "keyword.operator.element-specification.sun.gremlin" 92 | match: """(?x)\\b 93 | (ARC|BEZIER|BOTCENT|BOTLEFT|BOTRIGHT|BSPLINE|CENTCENT|CENTLEFT 94 | |CENTRIGHT|CURVE|POLYGON|TOPCENT|TOPLEFT|TOPRIGHT|VECTOR)\\b""" 95 | },{ 96 | match: "^\\s*([0-6])\\s+([0-9]+)\\s*$" 97 | captures: 98 | 1: name: "keyword.operator.element-brush.gremlin" 99 | 2: name: "keyword.operator.element-size.gremlin" 100 | },{ 101 | name: "comment.line.ignored.end-point-list.gremlin" 102 | match: "^\\s*(?:\\*|-1.0+\\s+-1.0+)\\s*$" 103 | },{ 104 | name: "keyword.operator.element-specification.aed.gremlin" 105 | match: "^\\s*[0-9]+(?:\\s*$|\\s+(?=\\d))" 106 | },{ 107 | match: """(?x) ^\\s* 108 | ( (6) \\s+ (\\S.{5}) 109 | | (5) \\s+ (\\S.{4}) 110 | | (4) \\s+ (\\S.{3}) 111 | | (3) \\s+ (\\S.{2}) 112 | | (2) \\s+ (\\S.{1}) 113 | | (1) \\s+ ([7-9\\D]) 114 | | ((?!0)\\d+) \\s+ (\\S.*) 115 | ) \\s* $""" 116 | captures: 117 | 1: name: "meta.element-text.gremlin" 118 | 2: name: "keyword.operator.character-count.6.gremlin" 119 | 3: name: "string.unquoted.gremlin" 120 | 4: name: "keyword.operator.character-count.5.gremlin" 121 | 5: name: "string.unquoted.gremlin" 122 | 6: name: "keyword.operator.character-count.4.gremlin" 123 | 7: name: "string.unquoted.gremlin" 124 | 8: name: "keyword.operator.character-count.3.gremlin" 125 | 9: name: "string.unquoted.gremlin" 126 | 10: name: "keyword.operator.character-count.2.gremlin" 127 | 11: name: "string.unquoted.gremlin" 128 | 12: name: "keyword.operator.character-count.1.gremlin" 129 | 13: name: "string.unquoted.gremlin" 130 | 14: name: "keyword.operator.character-count.gremlin" 131 | 15: name: "string.unquoted.gremlin" 132 | },{ 133 | name: "constant.numeric.decimal.gremlin" 134 | match: "\\d+(?:\\.\\d+)?" 135 | }] 136 | 137 | -------------------------------------------------------------------------------- /grammars/ideal.cson: -------------------------------------------------------------------------------- 1 | # IDEAL picture preprocessor 2 | scopeName: "source.ideal" 3 | patterns: [ 4 | {include: "#external"} 5 | {include: "#main"} 6 | ] 7 | 8 | repository: 9 | 10 | # Sensible handling of embedded processor source 11 | external: 12 | patterns: [include: "source.pic#tags", { 13 | 14 | # Roff lines 15 | begin: "^(?=[.'][ \\t]*(?:\\w|\\\\))" 16 | end: "(?" 157 | beginCaptures: 0: name: "punctuation.definition.bracket.angle.ideal" 158 | endCaptures: 0: name: "punctuation.definition.bracket.angle.ideal" 159 | }] 160 | 161 | 162 | strings: 163 | patterns: [{ 164 | 165 | # 'Single-quoted string' 166 | name: "string.quoted.single.ideal" 167 | begin: "'" 168 | end: "'" 169 | beginCaptures: 0: name: "punctuation.definition.string.begin.ideal" 170 | endCaptures: 0: name: "punctuation.definition.string.end.ideal" 171 | 172 | }, { 173 | # "Double-quoted string" 174 | name: "string.quoted.double.ideal" 175 | begin: '"' 176 | end: '"' 177 | beginCaptures: 0: name: "punctuation.definition.string.begin.ideal" 178 | endCaptures: 0: name: "punctuation.definition.string.end.ideal" 179 | patterns: [include: "#escapes"] 180 | }] 181 | 182 | 183 | # Local variables 184 | variables: 185 | begin: "\\b(var)\\b" 186 | end: "(?=;)" 187 | patterns: [include: "#punctuation"] 188 | beginCaptures: 189 | 1: name: "storage.type.var.ideal" 190 | -------------------------------------------------------------------------------- /grammars/manref.cson: -------------------------------------------------------------------------------- 1 | # Injected links to man(1) pages 2 | scopeName: "hidden.manref" 3 | injectionSelector: "text - (text.info | text.texinfo), comment, docstring, string.quoted.docstring, source.changelogs" 4 | patterns: [{ 5 | name: "manref" 6 | match: """(?xi) 7 | # Subject 8 | ((?: 9 | [^:\\s()<>/\"'`{}!&*\\#?\\\\] 10 | | 11 | # Avoid matching scheme component of “man:man(1)” URLs 12 | (?-i: (? { 17 | for(const file of packageFiles) 18 | disposables.add(...require(file)()); 19 | }); 20 | }, 21 | 22 | deactivate(){ 23 | if(null !== disposables){ 24 | disposables.dispose(); 25 | disposables = null; 26 | } 27 | }, 28 | 29 | createTroffView(state){ 30 | const fs = require("fs"); 31 | if(state.editorId || fs.existsSync(state.filePath) && fs.lstatSync(state.filePath).isFile()){ 32 | const TroffView = require("./lib/views/troff-view.js"); 33 | return new TroffView(state); 34 | } 35 | }, 36 | }; 37 | -------------------------------------------------------------------------------- /keymaps/keys.cson: -------------------------------------------------------------------------------- 1 | "atom-text-editor[data-grammar='text roff']": 2 | "tab": "language-roff:indent" 3 | "shift-tab": "language-roff:outdent" 4 | "{": "language-roff:curly-bracket" 5 | "(": "language-roff:round-bracket" 6 | "'": "language-roff:single-quote" 7 | 8 | ".platform-darwin atom-text-editor[data-grammar='text roff']": 9 | "cmd-e": "language-roff:eval-selection" 10 | 11 | ".platform-win32 atom-text-editor[data-grammar='text roff'], 12 | .platform-linux atom-text-editor[data-grammar='text roff']": 13 | "ctrl-e": "language-roff:eval-selection" 14 | 15 | ".platform-darwin, 16 | .platform-darwin atom-text-editor[class]": 17 | "cmd-m": "language-roff:open-manpage" 18 | 19 | ".platform-win32, .platform-win32 atom-text-editor[class], 20 | .platform-linux, .platform-linux atom-text-editor[class]": 21 | "ctrl-m": "language-roff:open-manpage" 22 | 23 | ".platform-darwin .troff-view": 24 | "cmd-a": "language-roff:select-all" 25 | 26 | ".platform-win32 .troff-view, 27 | .platform-linux .troff-view": 28 | "ctrl-a": "language-roff:select-all" 29 | -------------------------------------------------------------------------------- /lib/conversion.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const {existsSync} = require("fs"); 4 | const {join, parse} = require("path"); 5 | const {getGroffAdapter} = require("./utils.js"); 6 | 7 | // Preload adapter at startup to improve response time 8 | require("roff").GroffAdapter.loadDefault(); 9 | 10 | 11 | /** 12 | * Register commands for processing/converting Roff documents. 13 | * @return {Disposable[]} 14 | * @internal 15 | */ 16 | module.exports = () => [ 17 | atom.commands.add(buildSelector(), { 18 | "language-roff:save-as-dvi": ev => save(ev, "dvi"), 19 | "language-roff:save-as-html": ev => save(ev, "html"), 20 | "language-roff:save-as-pdf": ev => save(ev, "pdf"), 21 | "language-roff:save-as-ps": ev => save(ev, "ps"), 22 | "language-roff:save-as-ascii": ev => save(ev, "ascii"), 23 | "language-roff:save-as-utf8": ev => save(ev, "utf8"), 24 | "language-roff:save-as-dvi-landscape": ev => save(ev, "dvi", {landscape: true}), 25 | "language-roff:save-as-pdf-landscape": ev => save(ev, "pdf", {landscape: true}), 26 | "language-roff:save-as-ps-landscape": ev => save(ev, "ps", {landscape: true}), 27 | }), 28 | ]; 29 | 30 | 31 | /** 32 | * Construct the selector string for scoping conversion commands. 33 | * @return {String} 34 | * @private 35 | */ 36 | function buildSelector(){ 37 | return "atom-text-editor[data-grammar='text roff']" 38 | + ", atom-text-editor[data-grammar='source pic']" 39 | + ", .tree-view .file > .manpage-icon[data-path], .tab > .manpage-icon[data-path]" 40 | + ("1 2 3 4 5 6 7 8 9 chem man mdoc me ms n pic roff tr".split(/\s/) 41 | .map(ext => `, .tree-view .file > [data-path$=".${ext}"], .tab > [data-path$=".${ext}"]`) 42 | .join("\n")); 43 | } 44 | 45 | 46 | /** 47 | * Wrapper function which handles a specific "Save as…" command. 48 | * 49 | * @param {CustomEvent} event - Object describing the triggered event 50 | * @param {String} format - Lowercased name of format being saved to 51 | * @param {Object} [options] - Parameters passed to {@link GroffAdapter#format} 52 | * @private 53 | */ 54 | async function save(event, format, options = {}){ 55 | let editor = null; 56 | options = {auto: true, ...options}; 57 | 58 | const groff = await getGroffAdapter(); 59 | if(!groff) return; 60 | 61 | // macOS ships with Groff 1.19.2, which lacks a PDF driver 62 | if("pdf" === format && !groff.devices.pdf){ 63 | const text = "PDF output not supported by Groff installation"; 64 | let description = "Please upgrade Groff to the newest version, then restart Atom."; 65 | if("darwin" === process.platform) description += [, 66 | "You can install the latest Groff using [Homebrew](https://brew.sh/):", 67 | "~~~\nbrew install groff\n~~~", 68 | ].join("\n\n"); 69 | const note = atom.notifications.addError(text, {description, dismissable: true}); 70 | console.log(note); 71 | return; 72 | } 73 | 74 | if(event.target.matches("atom-text-editor, atom-text-editor *")){ 75 | editor = atom.workspace.getActiveTextEditor(); 76 | options.inputFile = editor.getPath(); 77 | } 78 | else options.inputFile = event.target.dataset.path; 79 | 80 | const ext = ("utf8" === format || "ascii" === format) ? "txt" : format; 81 | options.outputFile = getSaveLocation(options.inputFile, ext); 82 | if(!options.outputFile) return; 83 | 84 | let inputData = null; 85 | if(editor && !(options.inputFile && !editor.isModified() && existsSync(options.inputFile))) 86 | inputData = editor.getText(); 87 | 88 | try{ 89 | await groff.format(inputData, format, options); 90 | const text = "Saved to `" + options.outputFile + "`"; 91 | const note = atom.notifications.addSuccess(text, {dismissable: true}); 92 | setTimeout(() => note.dismiss(), 2000); 93 | } 94 | catch(error){ 95 | atom.notifications.addError(error.message, { 96 | detail: error.stack, 97 | dismissable: true, 98 | }); 99 | } 100 | } 101 | 102 | 103 | /** 104 | * Prompt the user for a system path to save to. 105 | * 106 | * @param {String} path 107 | * @param {String} format 108 | * @return {String} 109 | */ 110 | function getSaveLocation(path, format){ 111 | if(path){ 112 | const {dir, name} = parse(path); 113 | path = join(dir, `${name}.${format}`); 114 | } 115 | else if(path = atom.project.getPaths()[0]) 116 | path = join(path, "Untitled." + format); 117 | 118 | return atom.applicationDelegate.showSaveDialog({defaultPath: path}); 119 | } 120 | -------------------------------------------------------------------------------- /lib/hyperlinks.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const {Disposable} = require("atom"); 4 | const OPTION_NAME = "language-roff.linkManPageReferences"; 5 | 6 | 7 | module.exports = () => [ 8 | attachClickHandler(), 9 | atom.config.observe(OPTION_NAME, value => 10 | document.body.classList.toggle("disable-manref-links", !value)), 11 | ]; 12 | 13 | 14 | /** 15 | * Attach a listener to intercept `click` events. 16 | * 17 | * @param {String} [eventType="pointerdown"] 18 | * @return {Disposable} Removes listener when disposed. 19 | */ 20 | function attachClickHandler(eventType = "pointerdown"){ 21 | document.body.removeEventListener(eventType, handleClick); 22 | document.body.addEventListener(eventType, handleClick); 23 | return new Disposable(() => 24 | document.body.removeEventListener(eventType, handleClick)); 25 | } 26 | 27 | 28 | /** 29 | * Intercept a `click` event on a tokenised man-page reference. 30 | * 31 | * @param {MouseEvent|PointerEvent} event 32 | * @this {HTMLBodyElement} 33 | * @internal 34 | */ 35 | function handleClick(event){ 36 | let {target} = event; 37 | if(event.metaKey || event.ctrlKey || event.button > 0) return; // Respond to left-clicks only 38 | if(!atom.config.get(OPTION_NAME)) return; // User's disabled man-links 39 | if("object" !== typeof target || !target.classList) return; // Shouldn't happen 40 | 41 | if(target.classList.contains("syntax--manref") && target.closest("atom-text-editor")){ 42 | event.preventDefault(); 43 | event.stopImmediatePropagation(); 44 | if("syntax--manref" !== target.className) 45 | target = target.closest("atom-text-editor [class='syntax--manref']"); 46 | if(target){ 47 | const subject = (target.querySelector(".syntax--subject") || {}).textContent || ""; 48 | const section = (target.querySelector(".syntax--section") || {}).textContent || ""; 49 | const pageURL = `man://${subject}/${section.replace(/^\(|\)$/g, "")}`; 50 | atom.workspace.open(pageURL, {split: "right"}); 51 | } 52 | return false; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /lib/previewing.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const {getGroffAdapter, getManPrompt, getManAdapter} = require("./utils.js"); 4 | const {parseManURL, TTYRenderer} = require("roff"); 5 | let evalAdapter = null; 6 | 7 | 8 | module.exports = () => [ 9 | atom.workspace.addOpener(uri => { 10 | const page = parseManURL(uri); 11 | if(null !== page) 12 | return new (require("./views/troff-view.js"))(page); 13 | }), 14 | 15 | atom.commands.add("body", { 16 | "language-roff:eval-selection": () => evalSelection(), 17 | "language-roff:open-manpage": () => runOpenCmd(), 18 | "language-roff:clear-cached-data": () => runClearCmd(), 19 | }), 20 | ]; 21 | 22 | 23 | /** 24 | * Pipe the current selection through `groff -Tutf8` and display the output. 25 | * @internal 26 | */ 27 | async function evalSelection(){ 28 | const editor = atom.workspace.getActiveTextEditor(); 29 | const ranges = editor.getSelectionsOrderedByBufferPosition(); 30 | const source = ranges.map(range => range.getText()).join("") || editor.getText(); 31 | if(!source) return; 32 | evalAdapter = evalAdapter || new TTYRenderer(); 33 | const output = await (await getGroffAdapter()).format(source, "utf8", {raw: true}); 34 | let popup = atom.notifications.addInfo("Output of `groff -Tutf8`", { 35 | description: "```\n```\n", 36 | dismissable: true, 37 | }); 38 | popup = atom.views.getView(popup).element; 39 | const el = popup.querySelector("pre"); 40 | el.innerHTML = evalAdapter.process(output).trim(); 41 | el.className = "tty-output"; 42 | } 43 | 44 | 45 | /** 46 | * Display a notification indicating no entry was found for a queried topic. 47 | * 48 | * @param {String} name - Topic name 49 | * @param {String} [section=""] - Optional section name 50 | * @return {Notification} 51 | * @internal 52 | */ 53 | function notifyNothingMatched(name, section = ""){ 54 | const message = section 55 | ? `No manual entry found for \`${name}\` in section \`${section}\`.` 56 | : `No manual entry found for \`${name}\`.`; 57 | const options = {dismissable: true}; 58 | options.description = "This lookup may have been cached from an earlier call." 59 | + " If you believe this to be an error, clear the cache using the" 60 | + " `language-roff:clear-cached-data` command, then try again."; 61 | return atom.notifications.addError(message, options); 62 | } 63 | 64 | 65 | /** 66 | * Handler for the "open manual-page" command. 67 | * @return {Notification} 68 | * @internal 69 | */ 70 | async function runOpenCmd(){ 71 | let input = await getManPrompt().promptUser({ 72 | headerText: "Enter the name of a manual-page", 73 | footerHTML: "E.g., perl, 5 grep, grep(5)", 74 | }); 75 | 76 | if(input && (input = input.split(/\s+/).filter(Boolean))[0]){ 77 | const man = await getManAdapter(); 78 | const paths = await man.find(...input); 79 | paths[0] 80 | ? atom.workspace.open(`man://${input.join("/")}`) 81 | : notifyNothingMatched(...input); 82 | } 83 | } 84 | 85 | 86 | /** 87 | * Flush all cached lookups and loaded file data. 88 | * @internal 89 | */ 90 | async function runClearCmd(){ 91 | const man = await getManAdapter(); 92 | const {size} = man.cache; 93 | man.cache.clear(); 94 | const plural = size !== 1 ? "s" : ""; 95 | const message = `Cleared ${size} object${plural} from cache.`; 96 | atom.notifications.addInfo(message, {dismissable: true}); 97 | } 98 | -------------------------------------------------------------------------------- /lib/utils.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const {Disposable} = require("atom"); 4 | let promptView = null; 5 | let manAdapter = null; 6 | let groffAdapter = null; 7 | 8 | 9 | module.exports = { 10 | 11 | /** 12 | * Attach an external stylesheet to the workspace. 13 | * 14 | * @param {String} href - Path to CSS file 15 | * @param {Element} [parentElement] - DOM node to add to 16 | * @return {Disposable} Removes stylesheet from DOM when disposed 17 | */ 18 | attachStyleSheet(href, parentElement = null){ 19 | const link = document.createElement("link"); 20 | link.href = href; 21 | link.rel = "stylesheet"; 22 | link.type = "text/css"; 23 | 24 | (parentElement = parentElement || document.querySelector("atom-styles")) 25 | ? parentElement.insertBefore(link, parentElement.firstChild) 26 | : document.head.appendChild(link); 27 | 28 | return new Disposable(() => { 29 | if({parentElement} = link) 30 | parentElement.removeChild(link); 31 | }); 32 | }, 33 | 34 | 35 | /** 36 | * Stop a function from firing too quickly. 37 | * 38 | * Returns a copy of the original function that runs only after the designated 39 | * number of milliseconds have elapsed. Useful for throttling onResize handlers. 40 | * 41 | * @param {Function} fn - Function to debounce 42 | * @param {Number} [limit=0] - Threshold to stall execution by, in milliseconds. 43 | * @param {Boolean} [asap=false] - Call function *before* threshold elapses, not after. 44 | * @return {Function} 45 | */ 46 | debounce(fn, limit = 0, asap = false){ 47 | let started, context, args, timing; 48 | 49 | function delayed(){ 50 | const timeSince = Date.now() - started; 51 | if(timeSince >= limit){ 52 | if(!asap) fn.apply(context, args); 53 | if(timing) clearTimeout(timing); 54 | timing = context = args = null; 55 | } 56 | else timing = setTimeout(delayed, limit - timeSince); 57 | } 58 | 59 | // Debounced copy of original function 60 | return function(...args){ 61 | context = this; 62 | if(!limit) 63 | return fn.apply(context, args); 64 | started = Date.now(); 65 | if(!timing){ 66 | if(asap) fn.apply(context, args); 67 | timing = setTimeout(delayed, limit); 68 | } 69 | }; 70 | }, 71 | 72 | 73 | /** 74 | * Retrieve adapter instance for integrating with man(1). 75 | * 76 | * @return {ManAdapter} 77 | * @internal 78 | */ 79 | async getManAdapter(){ 80 | if(null === manAdapter){ 81 | const {ManAdapter} = require("roff"); 82 | manAdapter = await ManAdapter.loadDefault(); 83 | } 84 | return manAdapter; 85 | }, 86 | 87 | 88 | /** 89 | * Retrieve adapter instance for integrating with groff(1). 90 | * 91 | * @return {GroffAdapter} 92 | * @internal 93 | */ 94 | async getGroffAdapter(){ 95 | if(null === groffAdapter){ 96 | const {GroffAdapter} = require("roff"); 97 | try{ groffAdapter = await GroffAdapter.loadDefault(); } 98 | catch(error){ 99 | const text = "Unable to initialise Groff adapter."; 100 | console.error(error); 101 | 102 | // Assume Windows users haven't installed Groff yet 103 | if("win32" === process.platform){ 104 | const url = "https://www.gnu.org/software/groff/#downloading"; 105 | error = "[Download](" + url + ") and install Groff, then restart Atom."; 106 | } 107 | atom.notifications.addError(text, {description: error, dismissable: true}); 108 | } 109 | } 110 | return groffAdapter; 111 | }, 112 | 113 | 114 | /** 115 | * Retrieve view for querying users for input for man(1)-related commands. 116 | * 117 | * @return {PromptView} 118 | * @internal 119 | */ 120 | getManPrompt(){ 121 | if(null === promptView){ 122 | const PromptView = require("prompt-view"); 123 | promptView = new PromptView({ 124 | headerTagName: "label", 125 | headerClass: "prompt-header manpage-icon icon icon-book", 126 | footerClass: "prompt-footer message", 127 | }); 128 | } 129 | return promptView; 130 | }, 131 | }; 132 | -------------------------------------------------------------------------------- /lib/views/template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %TITLE% 6 | 20 |
21 | %CONTENT%
22 | 
23 | -------------------------------------------------------------------------------- /lib/views/troff-view.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const {join, parse} = require("path"); 4 | const {readFileSync, writeFileSync} = require("fs"); 5 | const {TTYRenderer, parseManURL} = require("roff"); 6 | const {debounce, getManAdapter, getGroffAdapter} = require("../utils.js"); 7 | const {CompositeDisposable, Disposable, Emitter} = require("atom"); 8 | 9 | 10 | /** 11 | * Class which displays rendered previews of roff(7) documents. 12 | * @internal 13 | * @class 14 | */ 15 | class TroffView{ 16 | 17 | constructor(page = {}){ 18 | this.renderer = new TTYRenderer(); 19 | this.disposables = new CompositeDisposable(); 20 | this.emitter = new Emitter(); 21 | 22 | // Pane-item element (outermost container) 23 | this.element = document.createElement("div"); 24 | this.element.className = "troff-view native-key-bindings"; 25 | this.element.tabIndex = -1; 26 | this.element.addEventListener("click", event => { 27 | const selector = "a[href^='man:']"; 28 | const link = event.target.matches(selector) ? event.target : event.target.closest(selector); 29 | if(link){ 30 | const page = parseManURL(link.href); 31 | this.loadPage(page.name, page.section); 32 | event.preventDefault(); 33 | event.stopImmediatePropagation(); 34 | } 35 | }); 36 | 37 | // Element directly inside this.element which receives rendered HTML 38 | this.content = this.element.appendChild(document.createElement("pre")); 39 | this.disposables.add( 40 | atom.commands.add(this.element, { 41 | "language-roff:select-all": this.selectAll.bind(this), 42 | "language-roff:edit-source": this.openInEditor.bind(this), 43 | "language-roff:save-as-html": this.saveAsHTML.bind(this), 44 | "language-roff:save-as-utf8": this.saveAsText.bind(this), 45 | }), 46 | atom.config.observe("editor.lineHeight", value => this.content.style.lineHeight = value), 47 | atom.config.observe("editor.fontFamily", value => this.content.style.fontFamily = value), 48 | atom.config.observe("editor.fontSize", value => { 49 | this.content.style.fontSize = value + "px"; 50 | this.render(); 51 | }) 52 | ); 53 | 54 | // Re-render content when element is resized 55 | const onResize = debounce(this.render.bind(this)); 56 | window.addEventListener("resize", onResize); 57 | this.disposables.add( 58 | new Disposable(() => window.removeEventListener("resize", onResize)), 59 | atom.workspace.observeActivePaneItem(onResize), 60 | atom.workspace.observePanes(pane => pane.onDidChangeFlexScale(onResize)) 61 | ); 62 | 63 | this.name = page.name || ""; 64 | this.section = page.section || ""; 65 | this.loadPage(page.name, page.section); 66 | } 67 | 68 | 69 | static deserialize(attr){ 70 | return new TroffView(attr); 71 | } 72 | 73 | serialize(){ 74 | return { 75 | deserializer: "TroffView", 76 | filePath: this.path, 77 | editorId: this.editorId, 78 | name: this.name, 79 | section: this.section, 80 | title: this.title, 81 | }; 82 | } 83 | 84 | 85 | destroy(){ 86 | this.emitter.emit("did-destroy"); 87 | this.emitter.dispose(); 88 | this.disposables.dispose(); 89 | this.element.remove(); 90 | } 91 | 92 | 93 | onDidChangeTitle(fn){ 94 | return this.emitter.on("did-change-title", fn); 95 | } 96 | 97 | 98 | getIconName(){ 99 | return "manpage"; 100 | } 101 | 102 | 103 | getURI(){ 104 | const frag = this.fragment ? "#" + this.fragment : ""; 105 | return `man://${this.name}/${this.section}` + frag; 106 | } 107 | 108 | 109 | getTitle(){ 110 | if(!this.name) return "Untitled"; 111 | let title = this.name; 112 | if(this.section) title += `(${this.section})`; 113 | return title; 114 | } 115 | 116 | 117 | getPath(){ 118 | return this.path || ""; 119 | } 120 | 121 | 122 | get isVisible(){ 123 | const pane = atom.workspace.paneForItem(this); 124 | return pane && pane.activeItem === this; 125 | } 126 | 127 | 128 | /** 129 | * Current width of the viewer's element, measured in columns. 130 | * @property {Number} width 131 | * @readonly 132 | */ 133 | get width(){ 134 | return Math.round(this.content.offsetWidth / atom.config.get("editor.fontSize") - 1); 135 | } 136 | 137 | 138 | async loadPage(name, section){ 139 | if(!name) return; 140 | const man = await getManAdapter(); 141 | const paths = await man.find(name, section); 142 | 143 | // Show an error if page couldn't be loaded 144 | if(!paths.length || !paths[0]) 145 | return atom.notifications.addError(section 146 | ? `No manual entry for ${name} in section ${section}` 147 | : `No manual entry for ${name}`); 148 | else{ 149 | this.path = paths[0]; 150 | this.name = name; 151 | this.section = section || this.sectionByFilename(this.path); 152 | this.emitter.emit("did-change-title"); 153 | this.source = await man.load(this.path); 154 | return this.render(); 155 | } 156 | } 157 | 158 | 159 | async render(){ 160 | if(!this.source || !this.isVisible) return; 161 | 162 | // Nothing's changed that warrants re-rendering 163 | const {lastRender, width, path} = this; 164 | if(lastRender && width === lastRender.width && path === lastRender.path) 165 | return; 166 | 167 | const groff = await getGroffAdapter(); 168 | const source = this.renderer.process(await groff.format(this.source, "utf8", { 169 | pageWidth: width + "v", 170 | auto: true, 171 | raw: true, 172 | })); 173 | if(source !== this.content.innerHTML){ 174 | this.content.innerHTML = source; 175 | if(!lastRender || lastRender.path !== path) 176 | this.element.scrollTop = 0; 177 | this.lastRender = {path, width}; 178 | } 179 | } 180 | 181 | 182 | async openInEditor(){ 183 | if(!this.path) return; 184 | const container = atom.workspace.paneContainerForItem(this); 185 | const activePane = atom.workspace.paneForItem(this); 186 | const panes = container.getPanes().filter(pane => pane !== activePane); 187 | return atom.workspace.open(this.path, panes.length ? {pane: panes.shift()} : {}); 188 | } 189 | 190 | 191 | /** 192 | * Save the rendered man-page as monospaced HTML. 193 | * @return {Promise} 194 | * @internal 195 | */ 196 | async saveAsHTML(){ 197 | const location = await this.getSaveLocation(".html"); 198 | if(!location) return; 199 | 200 | const viewStyle = window.getComputedStyle(this.element); 201 | const pageStyle = window.getComputedStyle(this.content); 202 | const source = readFileSync(join(__dirname, "template.html"), "utf8") 203 | .replace(/%TITLE%/g, parse(location).name) 204 | .replace(/%BG%/g, viewStyle.backgroundColor) 205 | .replace(/%FG%/g, pageStyle.color) 206 | .replace(/%SIZE%/g, atom.config.get("editor.fontSize") + "px") 207 | .replace(/%LEADING%/g, atom.config.get("editor.lineHeight")) 208 | .replace(/%FAMILY%/g, atom.config.get("editor.fontFamily")) 209 | .replace(/%CONTENT%/g, this.content.innerHTML); 210 | return this.saveFile(location, source); 211 | } 212 | 213 | 214 | /** 215 | * Save the rendered man-page as UTF8-encoded plain text. 216 | * @return {Promise} 217 | * @internal 218 | */ 219 | async saveAsText(){ 220 | const location = await this.getSaveLocation(".txt"); 221 | if(!location) return; 222 | return this.saveFile(location, this.content.textContent); 223 | } 224 | 225 | 226 | /** 227 | * Write a string to disk, and display a notification when successful. 228 | * 229 | * @param {String} location - Location to write to 230 | * @param {String} input - File content to be written 231 | * @return {Promise} 232 | * @internal 233 | */ 234 | async saveFile(location, input){ 235 | try{ 236 | writeFileSync(location, input, "utf8"); 237 | const text = "Saved to `" + location + "`"; 238 | const note = atom.notifications.addSuccess(text, {dismissable: true}); 239 | setTimeout(() => note.dismiss(), 2000); 240 | return note; 241 | } 242 | catch(error){ 243 | return atom.notifications.addError(error.message, { 244 | detail: error.stack, 245 | dismissable: true, 246 | }); 247 | } 248 | } 249 | 250 | 251 | /** 252 | * Prompt the user for a location to save to. 253 | * 254 | * @param {String} suffix - File extension with leading dot 255 | * @return {Promise} 256 | * @internal 257 | */ 258 | async getSaveLocation(suffix = ""){ 259 | const {name, section} = this; 260 | const filename = (name && section ? `${name}.${section}${suffix}` : name) || `Untitled${suffix}`; 261 | const defaultPath = join(atom.project.getPaths()[0] || require("os").homeDir(), filename); 262 | return atom.applicationDelegate.showSaveDialog({defaultPath}); 263 | } 264 | 265 | 266 | /** 267 | * Extract the section number from a man-page's path. 268 | * 269 | * @param {String} input 270 | * @return {String} 271 | * @internal 272 | */ 273 | sectionByFilename(input){ 274 | input = input.replace(/\\/g, "/"); 275 | 276 | // Extract from directory name if unambiguous 277 | if(/\/man\/man([0-9ln])\/[^/]+$/.test(input)) 278 | return RegExp.lastParen; 279 | 280 | else(/\.([0-9][^.\s/]*|l|n)(?:\.[^0-9][^.\s/]*)?$/.test(input)) 281 | ? RegExp.lastParen 282 | : ""; 283 | } 284 | 285 | 286 | /** 287 | * Intercept `core:select-all` to stop user selecting the entire workspace. 288 | * 289 | * @param {CustomEvent} event 290 | * @return {Boolean} Returns false. 291 | * @internal 292 | */ 293 | selectAll(event){ 294 | event.preventDefault(); 295 | event.stopPropagation(); 296 | if(this.loading) return false; 297 | 298 | const selection = window.getSelection(); 299 | selection.removeAllRanges(); 300 | const range = document.createRange(); 301 | range.selectNodeContents(this.element); 302 | selection.addRange(range); 303 | return false; 304 | } 305 | } 306 | 307 | module.exports = TroffView; 308 | -------------------------------------------------------------------------------- /menus/roff.cson: -------------------------------------------------------------------------------- 1 | menu: [ 2 | label: "Packages" 3 | submenu: [ 4 | label: "Roff" 5 | submenu: [ 6 | {label: "Open manual page", command: "language-roff:open-manpage"} 7 | {label: "Clear cached data", command: "language-roff:clear-cached-data"} 8 | ] 9 | ] 10 | ] 11 | "context-menu": 12 | ".troff-view": [ 13 | {label: "Edit Source", command: "language-roff:edit-source"} 14 | {label: "Save as HTML\u2026", command: "language-roff:save-as-html"} 15 | {label: "Save as Plain Text\u2026", command: "language-roff:save-as-utf8"} 16 | {label: "Select All", command: "language-roff:select-all"} 17 | ] 18 | 'atom-text-editor[data-grammar="text roff"], atom-text-editor[data-grammar="source pic"], 19 | .tree-view .file > .manpage-icon[data-path], .tab > .manpage-icon[data-path], 20 | .tree-view .file > [data-path$=".1"], .tab > [data-path$=".1"], 21 | .tree-view .file > [data-path$=".2"], .tab > [data-path$=".2"], 22 | .tree-view .file > [data-path$=".3"], .tab > [data-path$=".3"], 23 | .tree-view .file > [data-path$=".4"], .tab > [data-path$=".4"], 24 | .tree-view .file > [data-path$=".5"], .tab > [data-path$=".5"], 25 | .tree-view .file > [data-path$=".6"], .tab > [data-path$=".6"], 26 | .tree-view .file > [data-path$=".7"], .tab > [data-path$=".7"], 27 | .tree-view .file > [data-path$=".8"], .tab > [data-path$=".8"], 28 | .tree-view .file > [data-path$=".9"], .tab > [data-path$=".9"], 29 | .tree-view .file > [data-path$=".chem"], .tab > [data-path$=".chem"], 30 | .tree-view .file > [data-path$=".man"], .tab > [data-path$=".man"], 31 | .tree-view .file > [data-path$=".mdoc"], .tab > [data-path$=".mdoc"], 32 | .tree-view .file > [data-path$=".me"], .tab > [data-path$=".me"], 33 | .tree-view .file > [data-path$=".ms"], .tab > [data-path$=".ms"], 34 | .tree-view .file > [data-path$=".n"], .tab > [data-path$=".n"], 35 | .tree-view .file > [data-path$=".pic"], .tab > [data-path$=".pic"], 36 | .tree-view .file > [data-path$=".roff"], .tab > [data-path$=".roff"], 37 | .tree-view .file > [data-path$=".tr"], .tab > [data-path$=".tr"]': [ 38 | label: "Save as\u2026", 39 | submenu: [ 40 | {label: "HTML", command: "language-roff:save-as-html"} 41 | {label: "PDF", command: "language-roff:save-as-pdf"} 42 | {label: "PDF, Landscape", command: "language-roff:save-as-pdf-landscape"} 43 | {label: "PostScript", command: "language-roff:save-as-ps"} 44 | {label: "PostScript, Landscape", command: "language-roff:save-as-ps-landscape"} 45 | {label: "TeX DVI", command: "language-roff:save-as-dvi"} 46 | {label: "TeX DVI, Landscape", command: "language-roff:save-as-dvi-landscape"} 47 | {label: "Plain text, ASCII", command: "language-roff:save-as-ascii"} 48 | {label: "Plain text, UTF-8", command: "language-roff:save-as-utf8"} 49 | ] 50 | ] 51 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "language-roff", 3 | "version": "1.3.1", 4 | "description": "Atom support for Unix manual pages (Groff/Troff) and the historical RUNOFF language.", 5 | "keywords": ["Roff", "Groff", "Troff", "Nroff", "Typesetting", "RUNOFF", "DSR", "BSD", "Unix Manual Page", "Manpage", "man", 6 | "mandoc", "mdoc", "Ronn", "Ditroff", "Eqn", "Pic", "Chem", "DFORMAT", "Grap", "Refer", "Tbl", "IDEAL", "grn", "Plan9"], 7 | "repository": "https://github.com/Alhadis/language-roff", 8 | "author": "John Gardner ", 9 | "license": "ISC", 10 | "engines": {"atom": ">=1.35.0"}, 11 | "atomTestRunner": "atom-mocha", 12 | "scripts": { 13 | "lint": "npx eslint .", 14 | "test": "atom -t spec", 15 | "update-fixtures": "cd spec/fixtures && node update input/* && mv input/*.json output && node prune" 16 | }, 17 | "dependencies": { 18 | "prompt-view": "^1.0.0", 19 | "roff": "^0.2.0" 20 | }, 21 | "devDependencies": { 22 | "@alhadis/eslint-config": "^1.2.0", 23 | "atom-mocha": "^2.2.1", 24 | "eslint": "^6.4.0", 25 | "first-mate": "^7.4.3", 26 | "language-hyperlink": "atom/language-hyperlink" 27 | }, 28 | "deserializers": { 29 | "TroffView": "createTroffView" 30 | }, 31 | "configSchema": { 32 | "blankLineReplacement": { 33 | "type": "string", 34 | "title": "Blank-line replacement", 35 | "description": "Specify the string which replaces empty lines when running the `fix-blank-lines` command.", 36 | "default": ".", 37 | "order": 1 38 | }, 39 | "linkManPageReferences": { 40 | "type": "boolean", 41 | "title": "Link man-page references", 42 | "description": "Make references to `man(1)` pages clickable inside comments and markup.", 43 | "default": true, 44 | "order": 2 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /settings/editor.cson: -------------------------------------------------------------------------------- 1 | ".text.roff": 2 | editor: 3 | commentStart: ".\\\" " 4 | softWrap: true 5 | 6 | ".text.roff .refer": 7 | editor: 8 | commentStart: "# " 9 | 10 | ".source.pic": 11 | editor: 12 | commentStart: "# " 13 | increaseIndentPattern: "[\\[({:]\\s*$|\\.cstart\\b" 14 | decreaseIndentPattern: "^\\s*[\\])}]|\\.cend\\b" 15 | 16 | ".source.ideal": 17 | editor: 18 | commentStart: "/* " 19 | commentEnd: " */" 20 | 21 | ".source.ditroff": 22 | editor: 23 | commentStart: "# " 24 | tabLength: 8 25 | 26 | ".source.context": 27 | editor: 28 | commentStart: "% " 29 | 30 | ".source.gremlin": 31 | editor: 32 | commentStart: "" 33 | preferredLineLength: 127 34 | 35 | ".text.runoff": 36 | editor: 37 | commentStart: ".! " 38 | softWrap: true 39 | -------------------------------------------------------------------------------- /snippets/snippets.cson: -------------------------------------------------------------------------------- 1 | # NOTE: Each snippet has been duplicated to be used with or without a leading 2 | # period. If changes are made to one, ensure they're reflected in the other. 3 | # Atom snippets don't yet support multiple prefixes. See atom/snippets#107. 4 | 5 | ".text.roff": 6 | 7 | # Macro definition 8 | ".de": 9 | prefix: ".de" 10 | body: ".de ${1:NAME}\n.\t$3\n.." 11 | description: "Define a new macro" 12 | leftLabel: ".de" 13 | 14 | de: 15 | prefix: "de" 16 | body: ".de ${1:NAME}\n.\t$3\n.." 17 | description: "Define a new macro" 18 | leftLabel: ".de" 19 | 20 | 21 | # "If" block 22 | ".if": 23 | prefix: ".if" 24 | body: ".if ${1:COND} \\\\{\\\\\n.\t$2\n.\\\\}" 25 | description: "Multiline `if` statement" 26 | leftLabel: ".if" 27 | 28 | if: 29 | prefix: "if" 30 | body: ".if ${1:COND} \\\\{\\\\\n.\t$2\n.\\\\}" 31 | description: "Multiline `if` statement" 32 | leftLabel: ".if" 33 | 34 | 35 | # "If/else" block 36 | ".ie": 37 | prefix: ".ie" 38 | body: ".ie ${1:COND} \\\\{\\\\\n.\t$2\n.\\\\}\n.el \\\\{\\\\\n.\t$3\n.\\\\}" 39 | description: "Multiline `if/else` block" 40 | leftLabel: ".ie" 41 | 42 | ie: 43 | prefix: "ie" 44 | body: ".ie ${1:COND} \\\\{\\\\\n.\t$2\n.\\\\}\n.el \\\\{\\\\\n.\t$3\n.\\\\}" 45 | description: "Multiline `if/else` block" 46 | leftLabel: ".ie" 47 | 48 | 49 | # Manual pages 50 | manpage: 51 | prefix: "manpage" 52 | body: """ 53 | .TH ${1:PROGNAME} 1 54 | .SH NAME 55 | ${1:progname} \\- ${2:short description} 56 | .SH SYNOPSIS 57 | .B ${1:progname} 58 | ${3:[command-line options] 59 | .\\\\" TIP: Use the `opt` snippet to insert options here} 60 | .SH DESCRIPTION 61 | ${4:-- Extended description --} 62 | .SH OPTIONS 63 | ${5:-- Options --} 64 | .SH EXAMPLES 65 | ${6:-- Examples --} 66 | $7 67 | """ 68 | leftLabel: "man" 69 | description: "Template for a basic manual-page" 70 | descriptionMoreURL: "http://liw.fi/manpages/" 71 | 72 | opt: 73 | prefix: "opt" 74 | body: "[\\\\fB\\\\-${1:o}\\\\fR \\\\fI${2:value}\\\\fR]\n$3" 75 | leftLabel: "man" 76 | description: "Short option: [-o value]" 77 | 78 | optl: 79 | prefix: "optl" 80 | body: "[\\\\fB\\\\-\\\\-${1:option}\\\\fR \\\\fI${2:value}\\\\fR]\n$3" 81 | leftLabel: "man" 82 | description: "Long option: [--option value]" 83 | 84 | optinfo: 85 | prefix: "optinfo" 86 | body: '.TP\n.BI \\\\-${1:o} " ${2:value}" \\\\fR, "\\\\fB \\\\-\\\\-${3:option}" \\\\fR=\\\\fI${2:value}\\\\fR\n${4:Description}\n$5' 87 | leftLabel: "man" 88 | description: "Extended information about an option" 89 | descriptionMoreURL: "http://liw.fi/manpages/" 90 | 91 | sh: 92 | prefix: "sh" 93 | body: """. 94 | .\\\\" ${2:--------------------------------------------------------------------} 95 | .SH "${1:SECTION HEADING}" 96 | .\\\\" ${2:--------------------------------------------------------------------} 97 | .$3""" 98 | leftLabel: "man" 99 | description: "Bordered section heading" 100 | 101 | 102 | # Code snippets for manpages 103 | ".code": 104 | prefix: ".code" 105 | body: ".PP\n.nf\n.RS\n.ft C\n${1:Enter code block here}\n.ft\n.RE\n.fi\n.PP" 106 | leftLabel: "man" 107 | description: "Block of example code" 108 | descriptionMoreURL: "http://liw.fi/manpages/" 109 | 110 | code: 111 | prefix: "code" 112 | body: ".PP\n.nf\n.RS\n.ft C\n${1:Enter code block here}\n.ft\n.RE\n.fi\n.PP" 113 | leftLabel: "man" 114 | description: "Block of example code" 115 | descriptionMoreURL: "http://liw.fi/manpages/" 116 | 117 | 118 | 119 | # Mandoc template 120 | mandoc: 121 | prefix: "mandoc" 122 | body: """ 123 | .Dd $Mdocdate$ 124 | .Dt ${1:PROGNAME} 1 125 | .Os 126 | .Sh NAME 127 | .Nm ${1:progname} 128 | .Nd ${2:Short description} 129 | .Sh SYNOPSIS 130 | .Nm ${1:progname} 131 | .Op Fl ${3:options} 132 | .Ar ${4:arguments} 133 | .Sh DESCRIPTION 134 | ${5:-- Text --} 135 | .Sh ENVIRONMENT 136 | ${6:-- Text --} 137 | .Sh FILES 138 | ${7:-- Text --} 139 | .Sh EXIT STATUS 140 | ${8:-- Text --} 141 | .Sh EXAMPLES 142 | ${9:-- Text --} 143 | .Sh DIAGNOSTICS 144 | ${10:-- Text --} 145 | .Sh ERRORS 146 | ${11:-- Text --} 147 | .Sh SEE ALSO 148 | .Xr ${12:manpage} 1 149 | $13 150 | """ 151 | leftLabel: "mdoc" 152 | description: "Skeleton for a mandoc manual page" 153 | descriptionMoreURL: "http://mdocml.bsd.lv/man/mdoc.7.html" 154 | 155 | 156 | # Table template 157 | tbl: 158 | prefix: "tbl" 159 | body: ".TS\nallbox;\nl c c .\n${1:Header1}\t${2:Header2}\t${3:Header3}\n${4:Body1\tBody2\tBody3}\n.TE\n" 160 | leftLabel: "tbl" 161 | description: "Template for a 3-column bordered table" 162 | descriptionMoreURL: "http://linux.die.net/man/1/tbl" 163 | 164 | 165 | # Debugging message 166 | log: 167 | prefix: "log" 168 | body: ".tm ${1:Text}" 169 | leftLabel: ".tm" 170 | description: "Trace message to STDERR" 171 | 172 | 173 | ".source.pic": 174 | 175 | # DFORMAT block 176 | ".dformat": 177 | prefix: ".df" 178 | body: ".begin dformat\nstyle $1\n.end" 179 | 180 | dformat: 181 | prefix: "df" 182 | body: ".begin dformat\nstyle $1\n.end" 183 | 184 | 185 | # CHEM: Dextroamphetamine molecule 186 | dextroamphetamine: 187 | prefix: "dex" 188 | body: """ 189 | .cstart 190 | .ps 26 191 | size 28 192 | R1: 193 | ring double 1,2 3,4 5,6 194 | bond 60 from R1.V2 195 | bond 120 196 | A1: 197 | front bond down ; CH3 198 | bond 60 from A1 ; NH2 199 | .ps 200 | .cend 201 | """ 202 | -------------------------------------------------------------------------------- /spec/.mocharc.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = { 4 | ui: "bdd", 5 | slow: 3500, 6 | require: [ 7 | "chai/register-expect", 8 | "chai/register-should", 9 | ], 10 | }; 11 | -------------------------------------------------------------------------------- /spec/fixtures/input/art-1.pic: -------------------------------------------------------------------------------- 1 | .PS 2 | A: box "yin"; move; 3 | B: box "yang"; 4 | arrow right at 1/4 ; 5 | arrow left at 1/4 ; 6 | 7 | box wid 0.5 ht 0.5; 8 | box wid 0.75 ht 0.75 with .sw at last box .se; 9 | .PE 10 | 11 | .PS 12 | circle "x" 13 | circle "y" at 1st circle - (0.4, 0.6) 14 | circle "z" at 1st circle + (0.4, -0.6) 15 | arrow from 1st circle to 2nd circle chop 16 | arrow from 2nd circle to 3rd circle chop 17 | arrow from 3rd circle to 1st circle chop 18 | A: [ 19 | circle; 20 | line up 1 at last circle .n; 21 | line down 1 at last circle .s; 22 | line right 1 at last circle .e; 23 | line left 1 at last circle .w; 24 | box dashed with .nw at last circle .se + (0.2, -0.2); 25 | Caption: center of last box; 26 | ] 27 | .PE 28 | 29 | .PS 30 | # Plot a single jumper in a box, $1 is the on-off state. 31 | define jumper { [ 32 | shrinkfactor = 0.8; 33 | Outer: box invis wid 0.45 ht 1; 34 | # Count on end ] to reset these 35 | boxwid = Outer.wid * shrinkfactor / 2; 36 | boxht = Outer.ht * shrinkfactor / 2; 37 | box fill (!$1) with .s at center of Outer; 38 | box fill ($1) with .n at center of Outer; 39 | ] } 40 | 41 | undef jumper 42 | undef jumperblock 43 | .PE 44 | 45 | .PS 46 | copy "filename.pic" thru XY 47 | .PE 48 | 49 | .PS 50 | copy thru % circle at ($1,$2) % until "END" 51 | 1 2 52 | 3 4 53 | 5 6 54 | END 55 | box 56 | .PE 57 | 58 | .PS 59 | x = 14 60 | command ".ds string x is " x "." 61 | .PE 62 | \*[string] 63 | 64 | .PS 65 | sh { printf anything } 66 | .PE 67 | 68 | .PS 69 | pi = atan2(0,-1); 70 | for i = 0 to 2 * pi by 0.1 do { 71 | "-" at (i/2, 0); 72 | "." at (i/2, sin(i)/2); 73 | ":" at (i/2, cos(i)/2); 74 | } 75 | .PE 76 | 77 | .PS 78 | copy thru { … } until "__END__" 79 | .PE 80 | -------------------------------------------------------------------------------- /spec/fixtures/input/art-2.pic: -------------------------------------------------------------------------------- 1 | .PS 2 | # Draw a demonstration up left arrow with grid box overlay 3 | define gridarrow 4 | { 5 | move right 0.1 6 | [ 7 | {arrow up left $1;} 8 | box wid 0.5 ht 0.5 dotted with .nw at last arrow .end; 9 | for i = 2 to ($1 / 0.5) do 10 | { 11 | box wid 0.5 ht 0.5 dotted with .sw at last box .se; 12 | } 13 | move down from last arrow .center; 14 | [ 15 | sprintf("\fBarrow up left %g\fP", $1) 16 | ] 17 | ] 18 | move right 0.1 from last [] .e; 19 | } 20 | gridarrow(0.5); 21 | gridarrow(1); 22 | gridarrow(1.5); 23 | gridarrow(2); 24 | undef gridarrow 25 | .PE 26 | -------------------------------------------------------------------------------- /spec/fixtures/input/art-3.pic: -------------------------------------------------------------------------------- 1 | .PS 2 | print 1 3 | print -1 4 | print 1.5 5 | print -1.5 6 | print 1e0 7 | print 1E0 8 | print 1e+0 9 | print 1E+0 10 | print 1e-0 11 | print 1E-0 12 | print -1e0 13 | print -1E0 14 | print -1e+0 15 | print -1E+0 16 | print -1e-0 17 | print -1E-0 18 | print 1.5e0 19 | print 1.5E0 20 | print 1.5e+0 21 | print 1.5E+0 22 | print 1.5e-0 23 | print 1.5E-0 24 | print -1.5e0 25 | print -1.5E0 26 | print -1.5e+0 27 | print -1.5E+0 28 | print -1.5e-0 29 | print -1.5E-0 30 | print 1.e0 31 | print 1.E0 32 | print 1.e+0 33 | print 1.E+0 34 | print 1.e-0 35 | print 1.E-0 36 | print -1.e0 37 | print -1.E0 38 | print -1.e+0 39 | print -1.E+0 40 | print -1.e-0 41 | print -1.E-0 42 | .PE 43 | -------------------------------------------------------------------------------- /spec/fixtures/input/art.pikchr: -------------------------------------------------------------------------------- 1 | // Pikchr extensions 2 | /* https://pikchr.org/home/doc/trunk/doc/differences.md */ 3 | 4 | # 1. Unicode arrows 5 | <- ← ← ← 6 | -> → → → 7 | <-> ↔ ↔ 8 | 9 | # 2. New object types 10 | oval 11 | cylinder 12 | file 13 | dot 14 | 15 | # 3. Units other than inches 16 | 1.5in; 1.5 17 | 2.3cm 18 | 230mm 19 | 13pc 20 | 24pt 21 | 48px 22 | 23 | # 4. Chamfered corners 24 | box radius 15px 25 | arrow radius 10px 26 | 27 | # 5. Colours 28 | box color blue 29 | box fill lightgray 30 | box color white fill blue 31 | 32 | # 6. Border thickness 33 | box thickness 1.5 34 | box thin 35 | box thick 36 | box thick thick 37 | 38 | # 7. Text modifiers 39 | box "Emboldened" bold 40 | box "Italicised" italic 41 | box "Bigger" big 42 | box "Smaller" small 43 | line above aligned 44 | 45 | # 8. Auto-fitting 46 | box "Text" "labels" fit 47 | 48 | # 9. Percentile property values 49 | box "default" italic "box" italic 50 | move; box "width 150%" width 150% 51 | move; box "wid 75%" wid 75% 52 | 53 | # 10. Chop semantics 54 | arrow <-> from A to B chop "from A to B chop" aligned above 55 | 56 | # 11. `same as …` construct 57 | file same as last box 58 | 59 | # 12. Line paths 60 | go 1cm heading 45.0 61 | go 1cm 90.0 62 | go right until even with 100% 63 | close 64 | 65 | # 13. Positions 66 | 1cm above previous.n 67 | 1cm below previous.s 68 | 1cm left of previous.nw 69 | 1cm right of previous.se 70 | 1cm heading 45.0 from box.s 71 | 2nd vertex of first line 72 | cylinder "B" at 5cm heading 125 from A 73 | 74 | # 14. Prior objects 75 | last; previous 76 | 77 | # 15. C/C++ comments 78 | # Traditional comment 79 | // C++-style comment 80 | /* C comment */ 81 | 82 | /* <<<<<<<<<<<<<< 83 | <<<<*/ box /*>>>> 84 | >>>>>>>>>>>>>>>>> */ 85 | 86 | # 16. Variables beginning with `$` or `@` 87 | $argc 88 | @argv 89 | 90 | # 17. Assignment operators 91 | x = 1.5 92 | x += 1.5 93 | x -= 1.5 94 | x *= 1.5 95 | x /= 1.5 96 | x := 1.5 97 | 1/3 98 | circlerad *= 0.75 99 | 100 | !not && || == != >= <= < > 101 | 102 | 103 | 104 | arrow right 200% "Markdown" "Source" 105 | box rad 10px "Markdown" "Formatter" "(markdown.c)" fit 106 | arrow right 200% "HTML+SVG" "Output" 107 | arrow <-> down 70% from last box.s 108 | arrow ↔ down 70% from last box.s 109 | box same "Pikchr" "Formatter" "(pikchr.c)" fit 110 | 111 | line from 1cm right of previous.se to 3cm right of previous.ne \ 112 | "aligned" above aligned 113 | 114 | 115 | 116 | 117 | 118 | text "Foo" 119 | -------------------------------------------------------------------------------- /spec/fixtures/input/colours.pikchr: -------------------------------------------------------------------------------- 1 | circle "0xF0F8FF" fill AliceBlue 2 | circle "0xFAEBD7" fill AntiqueWhite 3 | circle "0x00FFFF" fill Aqua 4 | circle "0x7FFFD4" fill Aquamarine 5 | circle "0xF0FFFF" fill Azure 6 | circle "0xF5F5DC" fill Beige 7 | circle "0xFFE4C4" fill Bisque 8 | circle "0x000000" fill Black 9 | circle "0xFFEBCD" fill BlanchedAlmond 10 | circle "0x0000FF" fill Blue 11 | circle "0x8A2BE2" fill BlueViolet 12 | circle "0xA52A2A" fill Brown 13 | circle "0xDEB887" fill BurlyWood 14 | circle "0x5F9EA0" fill CadetBlue 15 | circle "0x7FFF00" fill Chartreuse 16 | circle "0xD2691E" fill Chocolate 17 | circle "0xFF7F50" fill Coral 18 | circle "0x6495ED" fill CornflowerBlue 19 | circle "0xFFF8DC" fill Cornsilk 20 | circle "0xDC143C" fill Crimson 21 | circle "0x00FFFF" fill Cyan 22 | circle "0x00008B" fill DarkBlue 23 | circle "0x008B8B" fill DarkCyan 24 | circle "0xB8860B" fill DarkGoldenrod 25 | circle "0xA9A9A9" fill DarkGray 26 | circle "0x006400" fill DarkGreen 27 | circle "0xA9A9A9" fill DarkGrey 28 | circle "0xBDB76B" fill DarkKhaki 29 | circle "0x8B008B" fill DarkMagenta 30 | circle "0x556B2F" fill DarkOliveGreen 31 | circle "0xFF8C00" fill DarkOrange 32 | circle "0x9932CC" fill DarkOrchid 33 | circle "0x8B0000" fill DarkRed 34 | circle "0xE9967A" fill DarkSalmon 35 | circle "0x8FBC8F" fill DarkSeaGreen 36 | circle "0x483D8B" fill DarkSlateBlue 37 | circle "0x2F4F4F" fill DarkSlateGray 38 | circle "0x2F4F4F" fill DarkSlateGrey 39 | circle "0x00CED1" fill DarkTurquoise 40 | circle "0x9400D3" fill DarkViolet 41 | circle "0xFF1493" fill DeepPink 42 | circle "0x00BFFF" fill DeepSkyBlue 43 | circle "0x696969" fill DimGray 44 | circle "0x696969" fill DimGrey 45 | circle "0x1E90FF" fill DodgerBlue 46 | circle "0xB22222" fill Firebrick 47 | circle "0xFFFAF0" fill FloralWhite 48 | circle "0x228B22" fill ForestGreen 49 | circle "0xFF00FF" fill Fuchsia 50 | circle "0xDCDCDC" fill Gainsboro 51 | circle "0xF8F8FF" fill GhostWhite 52 | circle "0xFFD700" fill Gold 53 | circle "0xDAA520" fill Goldenrod 54 | circle "0x808080" fill Gray 55 | circle "0x008000" fill Green 56 | circle "0xADFF2F" fill GreenYellow 57 | circle "0x808080" fill Grey 58 | circle "0xF0FFF0" fill Honeydew 59 | circle "0xFF69B4" fill HotPink 60 | circle "0xCD5C5C" fill IndianRed 61 | circle "0x4B0082" fill Indigo 62 | circle "0xFFFFF0" fill Ivory 63 | circle "0xF0E68C" fill Khaki 64 | circle "0xE6E6FA" fill Lavender 65 | circle "0xFFF0F5" fill LavenderBlush 66 | circle "0x7CFC00" fill LawnGreen 67 | circle "0xFFFACD" fill LemonChiffon 68 | circle "0xADD8E6" fill LightBlue 69 | circle "0xF08080" fill LightCoral 70 | circle "0xE0FFFF" fill LightCyan 71 | circle "0xFAFAD2" fill LightGoldenrodYellow 72 | circle "0xD3D3D3" fill LightGray 73 | circle "0x90EE90" fill LightGreen 74 | circle "0xD3D3D3" fill LightGrey 75 | circle "0xFFB6C1" fill LightPink 76 | circle "0xFFA07A" fill LightSalmon 77 | circle "0x20B2AA" fill LightSeaGreen 78 | circle "0x87CEFA" fill LightSkyBlue 79 | circle "0x778899" fill LightSlateGray 80 | circle "0x778899" fill LightSlateGrey 81 | circle "0xB0C4DE" fill LightSteelBlue 82 | circle "0xFFFFE0" fill LightYellow 83 | circle "0x00FF00" fill Lime 84 | circle "0x32CD32" fill LimeGreen 85 | circle "0xFAF0E6" fill Linen 86 | circle "0xFF00FF" fill Magenta 87 | circle "0x800000" fill Maroon 88 | circle "0x66CDAA" fill MediumAquamarine 89 | circle "0x0000CD" fill MediumBlue 90 | circle "0xBA55D3" fill MediumOrchid 91 | circle "0x9370DB" fill MediumPurple 92 | circle "0x3CB371" fill MediumSeaGreen 93 | circle "0x7B68EE" fill MediumSlateBlue 94 | circle "0x00FA9A" fill MediumSpringGreen 95 | circle "0x48D1CC" fill MediumTurquoise 96 | circle "0xC71585" fill MediumVioletRed 97 | circle "0x191970" fill MidnightBlue 98 | circle "0xF5FFFA" fill MintCream 99 | circle "0xFFE4E1" fill MistyRose 100 | circle "0xFFE4B5" fill Moccasin 101 | circle "0xFFDEAD" fill NavajoWhite 102 | circle "0x000080" fill Navy 103 | circle "-1" fill None 104 | circle "-1" fill Off 105 | circle "0xFDF5E6" fill OldLace 106 | circle "0x808000" fill Olive 107 | circle "0x6B8E23" fill OliveDrab 108 | circle "0xFFA500" fill Orange 109 | circle "0xFF4500" fill OrangeRed 110 | circle "0xDA70D6" fill Orchid 111 | circle "0xEEE8AA" fill PaleGoldenrod 112 | circle "0x98FB98" fill PaleGreen 113 | circle "0xAFEEEE" fill PaleTurquoise 114 | circle "0xDB7093" fill PaleVioletRed 115 | circle "0xFFEFD5" fill PapayaWhip 116 | circle "0xFFDAB9" fill PeachPuff 117 | circle "0xCD853F" fill Peru 118 | circle "0xFFC0CB" fill Pink 119 | circle "0xDDA0DD" fill Plum 120 | circle "0xB0E0E6" fill PowderBlue 121 | circle "0x800080" fill Purple 122 | circle "0x663399" fill RebeccaPurple 123 | circle "0xFF0000" fill Red 124 | circle "0xBC8F8F" fill RosyBrown 125 | circle "0x4169E1" fill RoyalBlue 126 | circle "0x8B4513" fill SaddleBrown 127 | circle "0xFA8072" fill Salmon 128 | circle "0xF4A460" fill SandyBrown 129 | circle "0x2E8B57" fill SeaGreen 130 | circle "0xFFF5EE" fill Seashell 131 | circle "0xA0522D" fill Sienna 132 | circle "0xC0C0C0" fill Silver 133 | circle "0x87CEEB" fill SkyBlue 134 | circle "0x6A5ACD" fill SlateBlue 135 | circle "0x708090" fill SlateGray 136 | circle "0x708090" fill SlateGrey 137 | circle "0xFFFAFA" fill Snow 138 | circle "0x00FF7F" fill SpringGreen 139 | circle "0x4682B4" fill SteelBlue 140 | circle "0xD2B48C" fill Tan 141 | circle "0x008080" fill Teal 142 | circle "0xD8BFD8" fill Thistle 143 | circle "0xFF6347" fill Tomato 144 | circle "0x40E0D0" fill Turquoise 145 | circle "0xEE82EE" fill Violet 146 | circle "0xF5DEB3" fill Wheat 147 | circle "0xFFFFFF" fill White 148 | circle "0xF5F5F5" fill WhiteSmoke 149 | circle "0xFFFF00" fill Yellow 150 | circle "0x9ACD32" fill YellowGreen 151 | -------------------------------------------------------------------------------- /spec/fixtures/input/context.sqtroff: -------------------------------------------------------------------------------- 1 | X ps 300 1 1 2 | Y P default letter 2550 3300 0 0 0 0 2550 3300 3 | x a 20 4 | x b 10 5 | x bd 2 3 6 | x cs 10 20 7 | x Slant 45 8 | x Height 20 9 | 10 | N n l 3 1234 11 | = (This is a test.) 12 | n 13 | 14 | N n l 3 1134 15 | = (This ) 16 | h 50 17 | f 10 TI 18 | = (is) 19 | h 50 20 | f 10 TR 21 | = ( a test.) 22 | n 23 | 24 | X impr 300 1 1 25 | Y P default letter 2550 3300 21 17 56 25 2400 3210 26 | P 1 27 | V 50 28 | O 289 29 | w 12 30 | L 1950 31 | I 0 32 | N b 1 6 1432 33 | f 10 TR 34 | k 0 1 35 | D w 0 36 | = (This is a sample line of text.) 37 | n 38 | N b 1 6 1308 39 | = (This is another sample line of text.) 40 | n 41 | N b 1 7 1230 42 | = (This is still another sample line of text.) 43 | n 44 | p 3300 45 | 46 | % Ordinary comment 47 | % D message 48 | % E Error message 49 | % I fp 2 HelveticaBold 50 | % T Trace line 51 | % W Warning message 52 | 53 | % Line drawing 54 | D a 2 1 2 0 55 | D b 100 100 56 | D c 500 57 | D e 500 700 58 | D f 99 59 | D l 100 500 60 | D t 7 61 | D w 128 62 | D ~ 0 0 100 100 63 | 64 | E cmd tr a-z A-Z 65 | E nl on 66 | E oc * 67 | E < /dev/null 68 | e Text passed directly to device 69 | 70 | f 12 Times New Roman 71 | h 140 72 | v -20 73 | I 4 74 | k 120 1 75 | L 77 76 | O 24 77 | 78 | N f j 8 480 79 | R h 10 ru 80 | R v 10 rn 81 | R t h 20 82 | R t v 10 83 | s -2 84 | V 15 85 | w 240 86 | = (O) 87 | z 88 | = (/) 89 | n 90 | 91 | 92 | z Invalid, unused arguments 93 | 94 | % A sentence logically can't be contained inside a bigger 95 | % sentence, so a nested line command doesn't make sense. 96 | N n l 2 840 97 | N n l 2 840 98 | n 99 | 100 | % An “n” without a corresponding “N” isn't valid either 101 | n 102 | 103 | % The following line isn't a valid Context command 104 | yeah nah garn m8 105 | -------------------------------------------------------------------------------- /spec/fixtures/input/ditroff.1: -------------------------------------------------------------------------------- 1 | \X'ps: exec \n(XY showpage' 2 | \X'html: \*(XY' 3 | \X'\*(XY' 4 | 5 | .output tFoo tBar 6 | .output x X tty: sgr 1 7 | .output # Device name is \*(.T 8 | .output D F g 9 | .output w0 0 10 | .output t\ 11 | Foo\ 12 | Bar 0 13 | 14 | .output # Comment. \ 15 | Also commented. 16 | Normal text. 17 | 18 | .ds TM \s'-0.5m'\uTM\d\s'+0.5m' 19 | .output # 20 | .output # COPY MODE: 21 | .output # \\*(TM gets interpreted: \*(TM 22 | .output # However, \\(tm does not: \(tm 23 | .output # \ 24 | Normal text; previous line ended with `\e `. 25 | -------------------------------------------------------------------------------- /spec/fixtures/input/ditroff.2: -------------------------------------------------------------------------------- 1 | x T s 2 | x res 1 2 3 3 | x init 4 | x font 1 s 5 | x font 2 s path/to/filename 1 6 | x pause 7 | x stop 8 | x trailer 9 | x Height 1 10 | x Height -23 3.1 11 | x Slant 1 12 | x X Anchor 1,2 foo 13 | x X Anchor foo 14 | x X BleedAt 1 2 3 4 15 | x X CropAt 1 2 3 4 16 | x X HorScale 23 17 | x X LC_CTYPE en_US.UTF-8 18 | x X Link 1,2,3,4 id 19 | x X Link id 20 | x X Link 21 | x X PaperSize 595000 842000 1 22 | x X PS command % It's real, baby 23 | x X PSSetup command 24 | x X SetColor 12.0 3 rgb 25 | x X SupplyFont font file 26 | x X Sync 27 | x X Track 1 28 | x X TrimAt 1 2 3 4 29 | x X ULink 1,2,3,4 http://URL 30 | x X ULink https://URL 31 | x X ULink 32 | x X any 33 | x any 34 | 35 | x X PDFMark: Bookmark 0 Text 36 | x X PDFMark: Author Gunnar Ritter 37 | x X PDFMark: Keywords Heirloom Documentation Tools, troff 38 | x X PDFMark: Title Heirloom Documentation Tools: Quickstart Guide 39 | x X PS: [ {Catalog} << /ViewerPreferences << /DisplayDocTitle true >> >> /PUT pdfmark 40 | 41 | x X ps: file /path/to/file.ps 42 | x X ps: mdef 1 = (Insert code here.) 43 | x X ps: def = (Insert code here.) 44 | x X ps: import file 1 2 3 4 5 6 45 | 46 | x X papersize=A1 47 | x X pdf: pdfpic /path/to/picture.pdf -L 3 4 5 48 | x X pdf: xrev 49 | x X pdf: markstart /ANN definition 50 | x X pdf: markend 51 | x X pdf: marksuspend 52 | x X pdf: markrestart 53 | x X pdf: transition SLIDE Blinds 1.645 H O 50 42.1 true 54 | x X pdf: background pagefillbox 0 0 100 100 1.5 55 | x X pdf: background off 56 | x X pdf: background footnote bottom 57 | x X tty: sgr 1 58 | x X pdf: pagename foo 59 | x X pdf: switchtopage after foo 60 | 61 | x X html:Foo 62 | x X html

: …could 63 | x X html: …you 64 | x X math: …not 65 | 66 | # Plan 9 troff2html(1) 67 | x X html manref start foo (1) 68 | x X html manref start foo 1 69 | x X html manref foo 1 70 | x X html manref end foo (1) 71 | x X html manref end foo 1 72 | 73 | # NFI what these are: 74 | x X index:3 75 | x X assertion:[ ] 76 | x X assertion:[x ] 77 | x X assertion:[y ] 78 | 79 | # Or these, really: 80 | x X devtag:.auto-image 81 | x X devtag:.br 82 | x X devtag:.ce 0 83 | x X devtag:.col 84 | x X devtag:.eo.h 85 | x X devtag:.eo.tl 86 | x X devtag:.eol 87 | x X devtag:.fi 88 | x X devtag:.in 89 | x X devtag:.ll 90 | x X devtag:.po 91 | x X devtag:.sp 92 | x X devtag:.ta 93 | x X devtag:.tab-te 94 | x X devtag:.tab-ts 95 | x X devtag:.ti 96 | x X devtag:.tl 97 | x X devtag:eol.ce 98 | x X devtag:tab 99 | x X devtag:tab 100 | x X devtag:tab0 101 | x X devtag:.fi 1 102 | x X devtag:.rj 0 103 | x X devtag:.in 0 104 | x X devtag:.ll 1560 105 | x X devtag:.po 0 106 | x X devtag:.ta L 120 L 240 107 | + L 360 L 480 L 600 L 720 L 840 108 | + L 960 L 1080 L 1200 L 1320 L 1440 L 1560 109 | 110 | # I've yet to start this project, lol: 111 | x X infer: start code js 112 | tfunction 113 | tfoo(bar){ 114 | t} 115 | x X infer: end code 116 | -------------------------------------------------------------------------------- /spec/fixtures/input/ditroff.3: -------------------------------------------------------------------------------- 1 | x T pdf 2 | x res 1 2 3 3 | x init 4 | 5 | # Heirloom Doctools 6 | x X PDFMark: Bookmark 7 | + 0 8 | + Text 9 | x X PDFMark: Author 10 | + Gunnar 11 | + Ritter 12 | x X PDFMark: Keywords 13 | + Heirloom Documentation Tools, 14 | + troff 15 | x X PDFMark: Title 16 | + Heirloom Documentation Tools: 17 | + Quickstart Guide 18 | x X PS: 19 | + [ 20 | + {Catalog} 21 | + << /ViewerPreferences << /DisplayDocTitle true >> >> 22 | + /PUT 23 | + pdfmark 24 | 25 | 26 | # GNU Troff 27 | x X ps: file 28 | + /path/to/file.ps 29 | x X ps: mdef 30 | + 1 = 31 | + (Insert code here.) 32 | x X ps: def 33 | + = 34 | + (Insert code here.) 35 | x X ps: import 36 | + ./file.ps -L 37 | + 1 2 3 38 | + 4 5 6 39 | -------------------------------------------------------------------------------- /spec/fixtures/input/do.roff: -------------------------------------------------------------------------------- 1 | .do aln ABC XYZ 2 | .do asciify XYZ 3 | .do class XYZ 4 | .do char XYZ xyz 5 | .do defcolor Octarine greenish-purple 6 | .do device ps: exec 3 4 add == 7 | .do output t String 8 | .do pi cat | tr a-z A-Z > /tmp/output-\n($$.txt 9 | .do pso /bin/date -R && echo "Executed successfully" 10 | .do sy curl -q "https://git.io/XYZ" | xc -j 'recent-posts/pages[0]' 11 | .do break 12 | .do tm Debugging feedback, etc 13 | .do ll 3m 14 | .do if \n(.g \fIgee\fP-roff 15 | .do ie t \fItee\fP-roff 16 | .do el \fIenn\fP-roff 17 | .do nr XY 55 18 | .do ds XY xy 19 | .do tl 'One'Two'Three' 20 | .do de1 FN 21 | .. 22 | .do de FN >> 23 | .>> 24 | .do ig >> 25 | .>> 26 | .do ig 27 | (?:(do)[ \\t]+)? 28 | 2: name: "entity.function.name.roff" 29 | .. 30 | .do cu 0 31 | #definition 32 | #ignore 33 | #underlines 34 | .do cu 1 35 | Underlined 36 | -------------------------------------------------------------------------------- /spec/fixtures/input/escapes.roff: -------------------------------------------------------------------------------- 1 | \n[.$] \En[.$] 2 | \n(.$ \En(.$ 3 | \n$ \En$ 4 | 5 | \*[xy z] \E*[xy z] 6 | \*(xy \E*(xy 7 | \*x \E*x 8 | 9 | \m[x] \Em[x] 10 | \m(xx \Em(xx 11 | \mx \Emx 12 | 13 | \s[+1] \Es[+1] 14 | \s+[1] \Es+[1] 15 | \s'1' \Es'1' 16 | \O2 \EO2 17 | \O5[xyz] \EO5[xyz] 18 | 19 | \V[x] \EV[x] 20 | \V(xx \EV(xx 21 | \Vx \EVx 22 | \?xx\? \E?xx\? 23 | \$* \E$* 24 | \$@ \E$@ 25 | \$^ \E$^ 26 | 27 | \$[32] \E$[32] 28 | \$(32 \E$(32 29 | \$1 \E$2 30 | 31 | \[aa] \E[aa] 32 | \(aa \E(aa 33 | 34 | \e \Ee 35 | \´ \E´ 36 | \` \E` 37 | \- \E- 38 | \0 \E0 39 | \| \E| 40 | \^ \E^ 41 | \& \E& 42 | \% \E% 43 | \c \Ec 44 | \d \Ed 45 | \p \Ep 46 | \r \Er 47 | \u \Eu 48 | 49 | \b'x' \Eb'x' 50 | \C'x' \EC'x' 51 | \D'x' \ED'x' 52 | \h'x' \Eh'x' 53 | \H'x' \EH'x' 54 | \S'x' \ES'x' 55 | \l'x' \El'x' 56 | \L'x' \EL'x' 57 | \o'x' \Eo'x' 58 | \v'x' \Ev'x' 59 | \x'x' \Ex'x' 60 | \w'x' \Ew'x' 61 | \X'x' \EX'x' 62 | \N'x' \EN'x' 63 | \!xyz 64 | \E!xyz 65 | 66 | \f(CW xyz \Ef(CW xyz 67 | \f(BI xyz \Ef(BI xyz 68 | \fB xyz \EfB xyz 69 | \fI xyz \EfI xyz 70 | \fR xyz \EfR xyz 71 | \f[xyz] \Ef[xyz] 72 | 73 | \f(XX \Ef(XX 74 | \fX \EfX 75 | \f5 \Ef5 76 | 77 | \gx \Egx 78 | \g(xx \Eg(xx 79 | \kX \EkX 80 | 81 | \s3 \Es3 82 | \s+3 \Es+3 83 | \s(32 \Es(32 84 | \s+(32 \Es+(32 85 | \s-(32 \Es-(32 86 | \zC \EzC 87 | 88 | '\E" 89 | '\E# 90 | .\E" 91 | .\E# 92 | 93 | \\ \E\ 94 | \t \Et 95 | \a \Ea 96 | \. \E. 97 | 98 | .ds 1 \EfIaaa 99 | xyz 100 | 101 | .ds 2 \EfBaaa 102 | xyz 103 | 104 | .ds 3 \Ef(BIaaa 105 | ll 106 | 107 | .Em III\E" 108 | III 109 | 110 | .Sy BBB\E" 111 | BBB 112 | 113 | .Li CCC\E" 114 | CCC 115 | 116 | .Lk https://a.com\E" 117 | -------------------------------------------------------------------------------- /spec/fixtures/input/font-BI.1: -------------------------------------------------------------------------------- 1 | .TH 2 | 3 | 4 | .BI BBBBBB IIII \ 5 | BBBBB III\ 6 | III \ 7 | \ 8 | BBB\ 9 | BBBB\ 10 | BB III \ 11 | \ 12 | B\ BB 13 | 14 | \" Comment Comment\ 15 | UUUUUU UUUUUUUU 16 | 17 | .BI BBBBBB\ 18 | IIII BBBBBB IIIII\\IIII" BBBBB IIIIIIIII\ 19 | \\IIIIII BBBBBBBB 20 | -------------------------------------------------------------------------------- /spec/fixtures/input/font-BI.2: -------------------------------------------------------------------------------- 1 | .TH 2 | 3 | .\" EDGE-CASE ISSUE: 4 | .BI "BBBBBBB" "IIIIII"BBBB\ 5 | UUUUUU "UUU"UU UUUU 6 | 7 | .\" This works, though: 8 | .BI "BBBBBBB" "IIIIII" BBBB\ 9 | BBBBBB "III"BB IIII 10 | 11 | 12 | 13 | 14 | .BI "BBBBBBB" III "" II\n(aaII BBBB" \ 15 | "II\n(aaII I\n(aaI 16 | UUUUUU " "UUU 17 | UU 18 | 19 | 20 | 21 | .BI "BBBBBBB"III\III" \ 22 | BBBBB "IIIII IIII 23 | 24 | UUU 25 | " UUUU "UUU\ 26 | UUUUUUUUUU UUU \U 27 | U 28 | 29 | .BI "BBBBBBB" III "BBBBB BBBB" \ 30 | "IIII III\ 31 | IIIIII " "BBB 32 | UU 33 | -------------------------------------------------------------------------------- /spec/fixtures/input/font-BI.3: -------------------------------------------------------------------------------- 1 | .TH 2 | 3 | .BI "BBBBBBB" IIIIII \ 4 | BBBBBB\ 5 | BBBBBB\ 6 | BBB III 7 | 8 | .BI "BBBBBBB" "IIIIII" BBBBB \ 9 | IIIIII\ 10 | IIIIII\ 11 | III BBB 12 | -------------------------------------------------------------------------------- /spec/fixtures/input/font-BR.1: -------------------------------------------------------------------------------- 1 | .TH 2 | 3 | 4 | .BR BBBBBB RRRR \ 5 | BBBBB RRR\ 6 | RRR \ 7 | \ 8 | BBB\ 9 | BBBB\ 10 | BB RRR \ 11 | \ 12 | B\ BB 13 | 14 | \" Comment Comment\ 15 | UUUUUU UUUUUUUU 16 | 17 | .BR BBBBBB\ 18 | RRRR BBBBBB RRRRR\\RRRR" BBBBB RRRRRRRRR\ 19 | \\RRRRRR BBBBBBBB 20 | -------------------------------------------------------------------------------- /spec/fixtures/input/font-BR.2: -------------------------------------------------------------------------------- 1 | .TH 2 | 3 | .\" EDGE-CASE ISSUE: 4 | .BR "BBBBBBB" "RRRRRR"BBBB\ 5 | UUUUUU "UUU"UU UUUU 6 | 7 | .\" This works, though: 8 | .BR "BBBBBBB" "RRRRRR" BBBB\ 9 | BBBBBB "RRR"BB RRRR 10 | 11 | 12 | 13 | 14 | .BR "BBBBBBB" RRR "" RR\n(aaRR BBBB" \ 15 | "RR\n(aaRR R\n(aaR 16 | UUUUUU " "UUU 17 | UU 18 | 19 | 20 | 21 | .BR "BBBBBBB"RRR\RRR" \ 22 | BBBBB "RRRRR RRRR 23 | 24 | UUU 25 | " UUUU "UUU\ 26 | UUUUUUUUUU UUU \U 27 | U 28 | 29 | .BR "BBBBBBB" RRR "BBBBB BBBB" \ 30 | "RRRR RRR\ 31 | RRRRRR " "BBB 32 | UU 33 | -------------------------------------------------------------------------------- /spec/fixtures/input/font-BR.3: -------------------------------------------------------------------------------- 1 | .TH 2 | 3 | .BR "BBBBBBB" RRRRRR \ 4 | BBBBBB\ 5 | BBBBBB\ 6 | BBB RRR 7 | 8 | .BR "BBBBBBB" "RRRRRR" BBBBB \ 9 | RRRRRR\ 10 | RRRRRR\ 11 | RRR BBB 12 | -------------------------------------------------------------------------------- /spec/fixtures/input/font-IB.1: -------------------------------------------------------------------------------- 1 | .TH 2 | 3 | 4 | .IB IIIIII BBBB \ 5 | IIIII BBB\ 6 | BBB \ 7 | \ 8 | III\ 9 | IIII\ 10 | II BBB \ 11 | \ 12 | I\ II 13 | 14 | \" Comment Comment\ 15 | UUUUUU UUUUUUUU 16 | 17 | .IB IIIIII\ 18 | BBBB IIIIII BBBBB\\BBBB" IIIII BBBBBBBBB\ 19 | \\BBBBBB IIIIIIII 20 | -------------------------------------------------------------------------------- /spec/fixtures/input/font-IB.2: -------------------------------------------------------------------------------- 1 | .TH 2 | 3 | .\" EDGE-CASE ISSUE: 4 | .IB "IIIIIII" "BBBBBB"IIII\ 5 | UUUUUU "UUU"UU UUUU 6 | 7 | .\" This works, though: 8 | .IB "IIIIIII" "BBBBBB" IIII\ 9 | IIIIII "BBB"II BBBB 10 | 11 | 12 | 13 | 14 | .IB "IIIIIII" BBB "" BB\n(aaBB IIII" \ 15 | "BB\n(aaBB B\n(aaB 16 | UUUUUU " "UUU 17 | UU 18 | 19 | 20 | 21 | .IB "IIIIIII"BBB\BBB" \ 22 | IIIII "BBBBB BBBB 23 | 24 | UUU 25 | " UUUU "UUU\ 26 | UUUUUUUUUU UUU \U 27 | U 28 | 29 | .IB "IIIIIII" BBB "IIIII IIII" \ 30 | "BBBB BBB\ 31 | BBBBBB " "III 32 | UU 33 | -------------------------------------------------------------------------------- /spec/fixtures/input/font-IB.3: -------------------------------------------------------------------------------- 1 | .TH 2 | 3 | .IB "IIIIIII" BBBBBB \ 4 | IIIIII\ 5 | IIIIII\ 6 | III BBB 7 | 8 | .IB "IIIIIII" "BBBBBB" IIIII \ 9 | BBBBBB\ 10 | BBBBBB\ 11 | BBB III 12 | -------------------------------------------------------------------------------- /spec/fixtures/input/font-IR.1: -------------------------------------------------------------------------------- 1 | .TH 2 | 3 | 4 | .IR IIIIII RRRR \ 5 | IIIII RRR\ 6 | RRR \ 7 | \ 8 | III\ 9 | IIII\ 10 | II RRR \ 11 | \ 12 | I\ II 13 | 14 | \" Comment Comment\ 15 | UUUUUU UUUUUUUU 16 | 17 | .IR IIIIII\ 18 | RRRR IIIIII RRRRR\\RRRR" IIIII RRRRRRRRR\ 19 | \\RRRRRR IIIIIIII 20 | -------------------------------------------------------------------------------- /spec/fixtures/input/font-IR.2: -------------------------------------------------------------------------------- 1 | .TH 2 | 3 | .\" EDGE-CASE ISSUE: 4 | .IR "IIIIIII" "RRRRRR"IIII\ 5 | UUUUUU "UUU"UU UUUU 6 | 7 | .\" This works, though: 8 | .IR "IIIIIII" "RRRRRR" IIII\ 9 | IIIIII "RRR"II RRRR 10 | 11 | 12 | 13 | 14 | .IR "IIIIIII" RRR "" RR\n(aaRR IIII" \ 15 | "RR\n(aaRR R\n(aaR 16 | UUUUUU " "UUU 17 | UU 18 | 19 | 20 | 21 | .IR "IIIIIII"RRR\RRR" \ 22 | IIIII "RRRRR RRRR 23 | 24 | UUU 25 | " UUUU "UUU\ 26 | UUUUUUUUUU UUU \U 27 | U 28 | 29 | .IR "IIIIIII" RRR "IIIII IIII" \ 30 | "RRRR RRR\ 31 | RRRRRR " "III 32 | UU 33 | -------------------------------------------------------------------------------- /spec/fixtures/input/font-IR.3: -------------------------------------------------------------------------------- 1 | .TH 2 | 3 | .IR "IIIIIII" RRRRRR \ 4 | IIIIII\ 5 | IIIIII\ 6 | III RRR 7 | 8 | .IR "IIIIIII" "RRRRRR" IIIII \ 9 | RRRRRR\ 10 | RRRRRR\ 11 | RRR III 12 | -------------------------------------------------------------------------------- /spec/fixtures/input/font-RB.1: -------------------------------------------------------------------------------- 1 | .TH 2 | 3 | 4 | .RB RRRRRR BBBB \ 5 | RRRRR BBB\ 6 | BBB \ 7 | \ 8 | RRR\ 9 | RRRR\ 10 | RR BBB \ 11 | \ 12 | R\ RR 13 | 14 | \" Comment Comment\ 15 | UUUUUU UUUUUUUU 16 | 17 | .RB RRRRRR\ 18 | BBBB RRRRRR BBBBB\\BBBB" RRRRR BBBBBBBBB\ 19 | \\BBBBBB RRRRRRRR 20 | -------------------------------------------------------------------------------- /spec/fixtures/input/font-RB.2: -------------------------------------------------------------------------------- 1 | .TH 2 | 3 | .\" EDGE-CASE ISSUE: 4 | .RB "RRRRRRR" "BBBBBB"RRRR\ 5 | UUUUUU "UUU"UU UUUU 6 | 7 | .\" This works, though: 8 | .RB "RRRRRRR" "BBBBBB" RRRR\ 9 | RRRRRR "BBB"RR BBBB 10 | 11 | 12 | 13 | 14 | .RB "RRRRRRR" BBB "" BB\n(aaBB RRRR" \ 15 | "BB\n(aaBB B\n(aaB 16 | UUUUUU " "UUU 17 | UU 18 | 19 | 20 | 21 | .RB "RRRRRRR"BBB\BBB" \ 22 | RRRRR "BBBBB BBBB 23 | 24 | UUU 25 | " UUUU "UUU\ 26 | UUUUUUUUUU UUU \U 27 | U 28 | 29 | .RB "RRRRRRR" BBB "RRRRR RRRR" \ 30 | "BBBB BBB\ 31 | BBBBBB " "RRR 32 | UU 33 | -------------------------------------------------------------------------------- /spec/fixtures/input/font-RB.3: -------------------------------------------------------------------------------- 1 | .TH 2 | 3 | .RB "RRRRRRR" BBBBBB \ 4 | RRRRRR\ 5 | RRRRRR\ 6 | RRR BBB 7 | 8 | .RB "RRRRRRR" "BBBBBB" RRRRR \ 9 | BBBBBB\ 10 | BBBBBB\ 11 | BBB RRR 12 | -------------------------------------------------------------------------------- /spec/fixtures/input/font-RI.1: -------------------------------------------------------------------------------- 1 | .TH 2 | 3 | 4 | .RI RRRRRR IIII \ 5 | RRRRR III\ 6 | III \ 7 | \ 8 | RRR\ 9 | RRRR\ 10 | RR III \ 11 | \ 12 | R\ RR 13 | 14 | \" Comment Comment\ 15 | UUUUUU UUUUUUUU 16 | 17 | .RI RRRRRR\ 18 | IIII RRRRRR IIIII\\IIII" RRRRR IIIIIIIII\ 19 | \\IIIIII RRRRRRRR 20 | -------------------------------------------------------------------------------- /spec/fixtures/input/font-RI.2: -------------------------------------------------------------------------------- 1 | .TH 2 | 3 | .\" EDGE-CASE ISSUE: 4 | .RI "RRRRRRR" "IIIIII"RRRR\ 5 | UUUUUU "UUU"UU UUUU 6 | 7 | .\" This works, though: 8 | .RI "RRRRRRR" "IIIIII" RRRR\ 9 | RRRRRR "III"RR IIII 10 | 11 | 12 | 13 | 14 | .RI "RRRRRRR" III "" II\n(aaII RRRR" \ 15 | "II\n(aaII I\n(aaI 16 | UUUUUU " "UUU 17 | UU 18 | 19 | 20 | 21 | .RI "RRRRRRR"III\III" \ 22 | RRRRR "IIIII IIII 23 | 24 | UUU 25 | " UUUU "UUU\ 26 | UUUUUUUUUU UUU \U 27 | U 28 | 29 | .RI "RRRRRRR" III "RRRRR RRRR" \ 30 | "IIII III\ 31 | IIIIII " "RRR 32 | UU 33 | -------------------------------------------------------------------------------- /spec/fixtures/input/font-RI.3: -------------------------------------------------------------------------------- 1 | .TH 2 | 3 | .RI "RRRRRRR" IIIIII \ 4 | RRRRRR\ 5 | RRRRRR\ 6 | RRR III 7 | 8 | .RI "RRRRRRR" "IIIIII" RRRRR \ 9 | IIIIII\ 10 | IIIIII\ 11 | III RRR 12 | -------------------------------------------------------------------------------- /spec/fixtures/input/links.1: -------------------------------------------------------------------------------- 1 | .[ Shorthand ]() , 2 | .[ Short\ hand ]() , 3 | .[ "Shor""t\ hand" ]() , 4 | 5 | .[ Shorthand ]<> , 6 | .[ Short\ hand ]<> , 7 | .[ "Shor""t\ hand" ]<> , 8 | 9 | .[ Shorthand ][] , 10 | .[ Short\ hand ][] , 11 | .[ "Shor""t\ hand" ][] , 12 | 13 | .[ Short ] , 14 | .[ Sh\ ort ] , 15 | .[ "S h o r t" ] , 16 | 17 | 18 | .[ Normal ]( https://url.com ) 19 | .[ Normal ][ anchor-id ] 20 | .[ Normal ]< email@address > 21 | .[ "Normal" ]( "https://url.com" ) 22 | .[ "Normal" ][ "anchor-id" ] 23 | .[ "Normal" ]< "email@address" > 24 | .[ Nor\ mal ]( https://ur\ l.com ) 25 | .[ Nor\ mal ][ anchor\ id ] 26 | .[ Nor\ mal ]< email\ address > 27 | 28 | .[ Long ]( before https://url.com after ) 29 | .[ "Long" ]( " ""before" "https://url.com" "after"" " ) 30 | .[ Long ][ before Anchor-Name after ] 31 | .[ "Long" ][ " ""before" "Anchor Name" "after"" " ] 32 | .[ Long ]< before email@address after > 33 | .[ "Long" ]< " ""before" email@address "after"" " > 34 | 35 | 36 | .\" Realistic examples 37 | .[ Details ]( " (visit " http://url " for more information" ) 38 | .[ Term-ID ][ " (q.v. " term-id ", section 3.2)" ] 39 | .[ "send an e-mail" ]< " to " email@address.com "" > 40 | -------------------------------------------------------------------------------- /spec/fixtures/output/art-3.pic.json: -------------------------------------------------------------------------------- 1 | [[ 2 | [".", "source.pic", "meta.function.begin.picture.section.macro.roff", "punctuation.definition.macro.roff"], 3 | ["PS", "source.pic", "meta.function.begin.picture.section.macro.roff", "entity.function.name.roff"] 4 | ],[ 5 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 6 | [" ", "source.pic", "source.embedded.pic"], 7 | ["1", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 8 | ],[ 9 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 10 | [" ", "source.pic", "source.embedded.pic"], 11 | ["-1", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 12 | ],[ 13 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 14 | [" ", "source.pic", "source.embedded.pic"], 15 | ["1.5", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 16 | ],[ 17 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 18 | [" ", "source.pic", "source.embedded.pic"], 19 | ["-1.5", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 20 | ],[ 21 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 22 | [" ", "source.pic", "source.embedded.pic"], 23 | ["1e0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 24 | ],[ 25 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 26 | [" ", "source.pic", "source.embedded.pic"], 27 | ["1E0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 28 | ],[ 29 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 30 | [" ", "source.pic", "source.embedded.pic"], 31 | ["1e+0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 32 | ],[ 33 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 34 | [" ", "source.pic", "source.embedded.pic"], 35 | ["1E+0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 36 | ],[ 37 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 38 | [" ", "source.pic", "source.embedded.pic"], 39 | ["1e-0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 40 | ],[ 41 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 42 | [" ", "source.pic", "source.embedded.pic"], 43 | ["1E-0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 44 | ],[ 45 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 46 | [" ", "source.pic", "source.embedded.pic"], 47 | ["-1e0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 48 | ],[ 49 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 50 | [" ", "source.pic", "source.embedded.pic"], 51 | ["-1E0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 52 | ],[ 53 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 54 | [" ", "source.pic", "source.embedded.pic"], 55 | ["-1e+0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 56 | ],[ 57 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 58 | [" ", "source.pic", "source.embedded.pic"], 59 | ["-1E+0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 60 | ],[ 61 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 62 | [" ", "source.pic", "source.embedded.pic"], 63 | ["-1e-0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 64 | ],[ 65 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 66 | [" ", "source.pic", "source.embedded.pic"], 67 | ["-1E-0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 68 | ],[ 69 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 70 | [" ", "source.pic", "source.embedded.pic"], 71 | ["1.5e0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 72 | ],[ 73 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 74 | [" ", "source.pic", "source.embedded.pic"], 75 | ["1.5E0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 76 | ],[ 77 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 78 | [" ", "source.pic", "source.embedded.pic"], 79 | ["1.5e+0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 80 | ],[ 81 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 82 | [" ", "source.pic", "source.embedded.pic"], 83 | ["1.5E+0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 84 | ],[ 85 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 86 | [" ", "source.pic", "source.embedded.pic"], 87 | ["1.5e-0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 88 | ],[ 89 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 90 | [" ", "source.pic", "source.embedded.pic"], 91 | ["1.5E-0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 92 | ],[ 93 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 94 | [" ", "source.pic", "source.embedded.pic"], 95 | ["-1.5e0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 96 | ],[ 97 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 98 | [" ", "source.pic", "source.embedded.pic"], 99 | ["-1.5E0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 100 | ],[ 101 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 102 | [" ", "source.pic", "source.embedded.pic"], 103 | ["-1.5e+0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 104 | ],[ 105 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 106 | [" ", "source.pic", "source.embedded.pic"], 107 | ["-1.5E+0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 108 | ],[ 109 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 110 | [" ", "source.pic", "source.embedded.pic"], 111 | ["-1.5e-0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 112 | ],[ 113 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 114 | [" ", "source.pic", "source.embedded.pic"], 115 | ["-1.5E-0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 116 | ],[ 117 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 118 | [" ", "source.pic", "source.embedded.pic"], 119 | ["1.e0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 120 | ],[ 121 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 122 | [" ", "source.pic", "source.embedded.pic"], 123 | ["1.E0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 124 | ],[ 125 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 126 | [" ", "source.pic", "source.embedded.pic"], 127 | ["1.e+0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 128 | ],[ 129 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 130 | [" ", "source.pic", "source.embedded.pic"], 131 | ["1.E+0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 132 | ],[ 133 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 134 | [" ", "source.pic", "source.embedded.pic"], 135 | ["1.e-0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 136 | ],[ 137 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 138 | [" ", "source.pic", "source.embedded.pic"], 139 | ["1.E-0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 140 | ],[ 141 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 142 | [" ", "source.pic", "source.embedded.pic"], 143 | ["-1.e0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 144 | ],[ 145 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 146 | [" ", "source.pic", "source.embedded.pic"], 147 | ["-1.E0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 148 | ],[ 149 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 150 | [" ", "source.pic", "source.embedded.pic"], 151 | ["-1.e+0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 152 | ],[ 153 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 154 | [" ", "source.pic", "source.embedded.pic"], 155 | ["-1.E+0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 156 | ],[ 157 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 158 | [" ", "source.pic", "source.embedded.pic"], 159 | ["-1.e-0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 160 | ],[ 161 | ["print", "source.pic", "source.embedded.pic", "storage.type.primitive.print.pic"], 162 | [" ", "source.pic", "source.embedded.pic"], 163 | ["-1.E-0", "source.pic", "source.embedded.pic", "constant.numeric.pic"] 164 | ],[ 165 | [".", "source.pic", "meta.function.end.picture.section.macro.roff", "punctuation.definition.macro.roff"], 166 | ["PE", "source.pic", "meta.function.end.picture.section.macro.roff", "entity.name.function.roff"] 167 | ]] -------------------------------------------------------------------------------- /spec/fixtures/output/ditroff.1.json: -------------------------------------------------------------------------------- 1 | [[ 2 | ["\\X'ps: e", "source.ditroff"], 3 | ["x", "source.ditroff", "meta.device-control.ditroff", "meta.device-control.lhs.ditroff", "keyword.operator.function.ditroff"], 4 | ["ec", "source.ditroff", "meta.device-control.ditroff", "meta.unknown-command.ditroff", "keyword.device.control.ditroff"], 5 | [" \\n(XY showpage'", "source.ditroff", "meta.device-control.ditroff", "meta.unknown-command.ditroff"] 6 | ],[ 7 | ["\\X'h", "source.ditroff"], 8 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 9 | ["ml:", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"], 10 | [" ", "source.ditroff", "meta.print-text.gnu.ditroff"], 11 | ["\\*(XY'", "source.ditroff", "comment.line.number-sign.ditroff"] 14 | ],[ 15 | ["\\X'\\*(XY'", "source.ditroff"] 16 | ],[ 17 | ["", "source.ditroff"] 18 | ],[ 19 | [".ou", "source.ditroff"], 20 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 21 | ["put", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"], 22 | [" ", "source.ditroff", "meta.print-text.gnu.ditroff"], 23 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 24 | ["Foo", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"], 25 | [" ", "source.ditroff", "meta.print-text.gnu.ditroff"], 26 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 27 | ["Bar", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"] 28 | ],[ 29 | [".ou", "source.ditroff"], 30 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 31 | ["put", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"], 32 | [" ", "source.ditroff", "meta.print-text.gnu.ditroff"], 33 | ["x", "source.ditroff", "meta.device-control.x-command.ditroff", "meta.device-control.lhs.ditroff", "keyword.operator.function.ditroff"], 34 | [" ", "source.ditroff", "meta.device-control.x-command.ditroff", "meta.device-control.lhs.ditroff"], 35 | ["X", "source.ditroff", "meta.device-control.x-command.ditroff", "meta.device-control.lhs.ditroff", "keyword.device.control.ditroff"], 36 | [" ", "source.ditroff", "meta.device-control.x-command.ditroff", "meta.device-control.lhs.ditroff"], 37 | ["tty", "source.ditroff", "meta.device-control.x-command.ditroff", "keyword.device.control.subcommand.gnu.ditroff"], 38 | [":", "source.ditroff", "meta.device-control.x-command.ditroff", "punctuation.separator.key-value.colon.ditroff"], 39 | [" ", "source.ditroff", "meta.device-control.x-command.ditroff"], 40 | ["sgr", "source.ditroff", "meta.device-control.x-command.ditroff", "keyword.control.directive.gnu.ditroff"], 41 | [" ", "source.ditroff", "meta.device-control.x-command.ditroff"], 42 | ["1", "source.ditroff", "meta.device-control.x-command.ditroff", "constant.numeric.ditroff"] 43 | ],[ 44 | [".ou", "source.ditroff"], 45 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 46 | ["put", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"], 47 | [" ", "source.ditroff", "meta.print-text.gnu.ditroff"], 48 | ["#", "source.ditroff", "comment.line.number-sign.ditroff", "punctuation.definition.comment.ditroff"], 49 | [" Device name is \\*(.T", "source.ditroff", "comment.line.number-sign.ditroff"] 50 | ],[ 51 | [".ou", "source.ditroff"], 52 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 53 | ["put", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"], 54 | [" ", "source.ditroff", "meta.print-text.gnu.ditroff"], 55 | ["D", "source.ditroff", "meta.graphics.unknown-command.ditroff", "keyword.operator.function.ditroff"], 56 | [" ", "source.ditroff", "meta.graphics.unknown-command.ditroff"], 57 | ["F", "source.ditroff", "meta.graphics.unknown-command.ditroff", "keyword.operator.subcommand.ditroff"], 58 | [" g", "source.ditroff", "meta.graphics.unknown-command.ditroff", "variable.parameter.ditroff"] 59 | ],[ 60 | [".ou", "source.ditroff"], 61 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 62 | ["put", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"], 63 | [" ", "source.ditroff", "meta.print-text.gnu.ditroff"], 64 | ["w", "source.ditroff", "keyword.operator.function.word-space.ditroff"], 65 | ["0 0", "source.ditroff"] 66 | ],[ 67 | [".ou", "source.ditroff"], 68 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 69 | ["put", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"], 70 | [" ", "source.ditroff", "meta.print-text.gnu.ditroff"], 71 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 72 | ["\\", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"] 73 | ],[ 74 | ["Foo\\", "source.ditroff"] 75 | ],[ 76 | ["Bar 0", "source.ditroff"] 77 | ],[ 78 | ["", "source.ditroff"] 79 | ],[ 80 | [".ou", "source.ditroff"], 81 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 82 | ["put", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"], 83 | [" ", "source.ditroff", "meta.print-text.gnu.ditroff"], 84 | ["#", "source.ditroff", "comment.line.number-sign.ditroff", "punctuation.definition.comment.ditroff"], 85 | [" Comment. \\", "source.ditroff", "comment.line.number-sign.ditroff"] 86 | ],[ 87 | ["Also ", "source.ditroff"], 88 | ["c", "source.ditroff", "meta.print-character.ditroff", "keyword.operator.function.ditroff"], 89 | ["o", "source.ditroff", "meta.print-character.ditroff", "constant.character.ditroff"], 90 | ["mmen", "source.ditroff"], 91 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 92 | ["ed.", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"] 93 | ],[ 94 | ["Normal ", "source.ditroff"], 95 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 96 | ["ext.", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"] 97 | ],[ 98 | ["", "source.ditroff"] 99 | ],[ 100 | [".ds TM \\s'-0.5m'\\uTM\\d\\s'+0.5m'", "source.ditroff"] 101 | ],[ 102 | [".ou", "source.ditroff"], 103 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 104 | ["put", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"], 105 | [" ", "source.ditroff", "meta.print-text.gnu.ditroff"], 106 | ["#", "source.ditroff", "comment.line.number-sign.ditroff", "punctuation.definition.comment.ditroff"] 107 | ],[ 108 | [".ou", "source.ditroff"], 109 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 110 | ["put", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"], 111 | [" ", "source.ditroff", "meta.print-text.gnu.ditroff"], 112 | ["#", "source.ditroff", "comment.line.number-sign.ditroff", "punctuation.definition.comment.ditroff"], 113 | [" COPY MODE:", "source.ditroff", "comment.line.number-sign.ditroff"] 114 | ],[ 115 | [".ou", "source.ditroff"], 116 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 117 | ["put", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"], 118 | [" ", "source.ditroff", "meta.print-text.gnu.ditroff"], 119 | ["#", "source.ditroff", "comment.line.number-sign.ditroff", "punctuation.definition.comment.ditroff"], 120 | [" \\\\*(TM gets interpreted: \\*(TM", "source.ditroff", "comment.line.number-sign.ditroff"] 121 | ],[ 122 | [".ou", "source.ditroff"], 123 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 124 | ["put", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"], 125 | [" ", "source.ditroff", "meta.print-text.gnu.ditroff"], 126 | ["#", "source.ditroff", "comment.line.number-sign.ditroff", "punctuation.definition.comment.ditroff"], 127 | [" However, \\\\(tm does not: \\(tm", "source.ditroff", "comment.line.number-sign.ditroff"] 128 | ],[ 129 | [".ou", "source.ditroff"], 130 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 131 | ["put", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"], 132 | [" ", "source.ditroff", "meta.print-text.gnu.ditroff"], 133 | ["#", "source.ditroff", "comment.line.number-sign.ditroff", "punctuation.definition.comment.ditroff"], 134 | [" \\ ", "source.ditroff", "comment.line.number-sign.ditroff"] 135 | ],[ 136 | ["Normal ", "source.ditroff"], 137 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 138 | ["ext;", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"], 139 | [" ", "source.ditroff", "meta.print-text.gnu.ditroff"], 140 | ["previous line ended ", "source.ditroff"], 141 | ["w", "source.ditroff", "keyword.operator.function.word-space.ditroff"], 142 | ["i", "source.ditroff"], 143 | ["t", "source.ditroff", "meta.print-text.gnu.ditroff", "keyword.operator.function.ditroff", "punctuation.definition.entity.ditroff"], 144 | ["h", "source.ditroff", "meta.print-text.gnu.ditroff", "string.quoted.double.ditroff"], 145 | [" ", "source.ditroff", "meta.print-text.gnu.ditroff"], 146 | ["`\\e `.", "source.ditroff"] 147 | ]] -------------------------------------------------------------------------------- /spec/fixtures/output/font-BI.1.json: -------------------------------------------------------------------------------- 1 | [[ 2 | [".", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "punctuation.definition.macro.roff"], 3 | ["TH", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "entity.name.function.roff"] 4 | ],[ 5 | ["", "text.roff"] 6 | ],[ 7 | ["", "text.roff"] 8 | ],[ 9 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 10 | ["BI", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 11 | [" ", "text.roff", "markup.bold.roff"], 12 | ["BBBBBB", "text.roff", "markup.bold.roff"], 13 | [" ", "text.roff", "markup.bold.roff"], 14 | ["IIII", "text.roff", "markup.italic.roff"], 15 | [" ", "text.roff", "markup.bold.roff"], 16 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 17 | ["", "text.roff", "markup.bold.roff"] 18 | ],[ 19 | [" ", "text.roff", "markup.bold.roff"], 20 | ["BBBBB", "text.roff", "markup.bold.roff"], 21 | [" ", "text.roff", "markup.bold.roff"], 22 | ["III", "text.roff", "markup.italic.roff"], 23 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 24 | ],[ 25 | ["III", "text.roff", "markup.italic.roff"], 26 | [" ", "text.roff", "markup.bold.roff"], 27 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 28 | ["", "text.roff", "markup.bold.roff"] 29 | ],[ 30 | [" ", "text.roff", "markup.bold.roff"], 31 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 32 | ["", "text.roff", "markup.bold.roff"] 33 | ],[ 34 | [" ", "text.roff", "markup.bold.roff"], 35 | ["BBB", "text.roff", "markup.bold.roff"], 36 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 37 | ],[ 38 | ["BBBB", "text.roff", "markup.bold.roff"], 39 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 40 | ],[ 41 | ["BB", "text.roff", "markup.bold.roff"], 42 | [" ", "text.roff", "markup.bold.roff"], 43 | ["III", "text.roff", "markup.italic.roff"], 44 | [" ", "text.roff", "markup.bold.roff"], 45 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 46 | ["", "text.roff", "markup.bold.roff"] 47 | ],[ 48 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 49 | ],[ 50 | ["B", "text.roff", "markup.italic.roff"], 51 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.space.roff", "punctuation.definition.escape.roff"], 52 | [" ", "text.roff", "markup.italic.roff", "constant.character.escape.space.roff"], 53 | ["BB", "text.roff", "markup.italic.roff"] 54 | ],[ 55 | ["", "text.roff"] 56 | ],[ 57 | ["\\\"", "text.roff", "comment.line.roff", "punctuation.definition.comment.roff"], 58 | [" Comment Comment\\", "text.roff", "comment.line.roff"] 59 | ],[ 60 | ["UUUUUU UUUUUUUU", "text.roff"] 61 | ],[ 62 | ["", "text.roff"] 63 | ],[ 64 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 65 | ["BI", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 66 | [" ", "text.roff", "markup.bold.roff"], 67 | ["BBBBBB", "text.roff", "markup.bold.roff"], 68 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 69 | ],[ 70 | [" ", "text.roff", "markup.bold.roff"], 71 | ["IIII", "text.roff", "markup.italic.roff"], 72 | [" ", "text.roff", "markup.bold.roff"], 73 | ["BBBBBB", "text.roff", "markup.bold.roff"], 74 | [" ", "text.roff", "markup.bold.roff"], 75 | ["IIIII", "text.roff", "markup.italic.roff"], 76 | ["\\", "text.roff", "markup.italic.roff", "punctuation.definition.concealed.escape.backslash.roff"], 77 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.misc.roff", "punctuation.definition.escape.roff"], 78 | ["I", "text.roff", "markup.italic.roff", "constant.character.escape.misc.roff"], 79 | ["III", "text.roff", "markup.italic.roff"], 80 | ["\"", "text.roff", "markup.italic.roff"], 81 | [" ", "text.roff", "markup.bold.roff"], 82 | ["BBBBB", "text.roff", "markup.bold.roff"], 83 | [" ", "text.roff", "markup.bold.roff"], 84 | ["IIIIIIIII", "text.roff", "markup.italic.roff"], 85 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 86 | ],[ 87 | ["\\", "text.roff", "markup.italic.roff", "punctuation.definition.concealed.escape.backslash.roff"], 88 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.misc.roff", "punctuation.definition.escape.roff"], 89 | ["I", "text.roff", "markup.italic.roff", "constant.character.escape.misc.roff"], 90 | ["IIIII", "text.roff", "markup.italic.roff"], 91 | [" ", "text.roff", "markup.bold.roff"], 92 | ["BBBBBBBB", "text.roff", "markup.bold.roff"] 93 | ]] -------------------------------------------------------------------------------- /spec/fixtures/output/font-BI.2.json: -------------------------------------------------------------------------------- 1 | [[ 2 | [".", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "punctuation.definition.macro.roff"], 3 | ["TH", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "entity.name.function.roff"] 4 | ],[ 5 | ["", "text.roff"] 6 | ],[ 7 | [".", "text.roff", "comment.line.roff", "punctuation.definition.comment.roff"], 8 | ["\\\"", "text.roff", "comment.line.roff", "punctuation.definition.comment.roff"], 9 | [" EDGE-CASE ISSUE:", "text.roff", "comment.line.roff"] 10 | ],[ 11 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 12 | ["BI", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 13 | [" ", "text.roff", "markup.bold.roff"], 14 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 15 | ["BBBBBBB", "text.roff", "markup.bold.roff"], 16 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 17 | [" ", "text.roff", "markup.bold.roff"], 18 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.begin.roff"], 19 | ["IIIIII", "text.roff", "markup.italic.roff"], 20 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.end.roff"], 21 | ["BBBB\\", "text.roff", "markup.bold.roff"], 22 | ["", "text.roff"] 23 | ],[ 24 | ["UUUUUU \"UUU\"UU UUUU", "text.roff"] 25 | ],[ 26 | ["", "text.roff"] 27 | ],[ 28 | [".", "text.roff", "comment.line.roff", "punctuation.definition.comment.roff"], 29 | ["\\\"", "text.roff", "comment.line.roff", "punctuation.definition.comment.roff"], 30 | [" This works, though:", "text.roff", "comment.line.roff"] 31 | ],[ 32 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 33 | ["BI", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 34 | [" ", "text.roff", "markup.bold.roff"], 35 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 36 | ["BBBBBBB", "text.roff", "markup.bold.roff"], 37 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 38 | [" ", "text.roff", "markup.bold.roff"], 39 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.begin.roff"], 40 | ["IIIIII", "text.roff", "markup.italic.roff"], 41 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.end.roff"], 42 | [" ", "text.roff", "markup.bold.roff"], 43 | ["BBBB", "text.roff", "markup.bold.roff"], 44 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 45 | ],[ 46 | ["BBBBBB", "text.roff", "markup.bold.roff"], 47 | [" ", "text.roff", "markup.bold.roff"], 48 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.begin.roff"], 49 | ["III", "text.roff", "markup.italic.roff"], 50 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.end.roff"], 51 | ["BB ", "text.roff", "markup.bold.roff"], 52 | ["IIII", "text.roff", "markup.italic.roff"] 53 | ],[ 54 | ["", "text.roff"] 55 | ],[ 56 | ["", "text.roff"] 57 | ],[ 58 | ["", "text.roff"] 59 | ],[ 60 | ["", "text.roff"] 61 | ],[ 62 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 63 | ["BI", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 64 | [" ", "text.roff", "markup.bold.roff"], 65 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 66 | ["BBBBBBB", "text.roff", "markup.bold.roff"], 67 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 68 | [" ", "text.roff", "markup.bold.roff"], 69 | ["III", "text.roff", "markup.italic.roff"], 70 | [" ", "text.roff", "markup.bold.roff"], 71 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 72 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 73 | [" ", "text.roff", "markup.bold.roff"], 74 | ["II", "text.roff", "markup.italic.roff"], 75 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff", "punctuation.definition.escape.roff"], 76 | ["n", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff"], 77 | ["(", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff", "punctuation.definition.brace.roff"], 78 | ["aa", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "variable.parameter.roff"], 79 | ["II", "text.roff", "markup.italic.roff"], 80 | [" ", "text.roff", "markup.bold.roff"], 81 | ["BBBB", "text.roff", "markup.bold.roff"], 82 | ["\"", "text.roff", "markup.bold.roff"], 83 | [" ", "text.roff", "markup.bold.roff"], 84 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 85 | ],[ 86 | [" ", "text.roff", "constant.character.escape.newline.roff"], 87 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.begin.roff"], 88 | ["II", "text.roff", "markup.italic.roff"], 89 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff", "punctuation.definition.escape.roff"], 90 | ["n", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff"], 91 | ["(", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff", "punctuation.definition.brace.roff"], 92 | ["aa", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "variable.parameter.roff"], 93 | ["II I", "text.roff", "markup.italic.roff"], 94 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff", "punctuation.definition.escape.roff"], 95 | ["n", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff"], 96 | ["(", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff", "punctuation.definition.brace.roff"], 97 | ["aa", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "variable.parameter.roff"], 98 | ["I", "text.roff", "markup.italic.roff"] 99 | ],[ 100 | ["UUUUUU \" \"UUU ", "text.roff"] 101 | ],[ 102 | ["UU", "text.roff"] 103 | ],[ 104 | ["", "text.roff"] 105 | ],[ 106 | ["", "text.roff"] 107 | ],[ 108 | ["", "text.roff"] 109 | ],[ 110 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 111 | ["BI", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 112 | [" ", "text.roff", "markup.bold.roff"], 113 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 114 | ["BBBBBBB", "text.roff", "markup.bold.roff"], 115 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 116 | ["III", "text.roff", "markup.italic.roff"], 117 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.misc.roff", "punctuation.definition.escape.roff"], 118 | ["I", "text.roff", "markup.italic.roff", "constant.character.escape.misc.roff"], 119 | ["II", "text.roff", "markup.italic.roff"], 120 | ["\"", "text.roff", "markup.italic.roff"], 121 | [" ", "text.roff", "markup.bold.roff"], 122 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 123 | ["", "text.roff", "markup.bold.roff"] 124 | ],[ 125 | [" ", "text.roff", "markup.bold.roff"], 126 | ["BBBBB", "text.roff", "markup.bold.roff"], 127 | [" ", "text.roff", "markup.bold.roff"], 128 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.begin.roff"], 129 | ["IIIII III", "text.roff", "markup.italic.roff"], 130 | ["I", "text.roff", "markup.italic.roff"] 131 | ],[ 132 | ["", "text.roff"] 133 | ],[ 134 | ["UUU", "text.roff"] 135 | ],[ 136 | ["\" UUUU \"UUU", "text.roff"], 137 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 138 | ],[ 139 | ["UUUUUUUUUU UUU ", "text.roff"], 140 | ["\\", "text.roff", "constant.character.escape.misc.roff", "punctuation.definition.escape.roff"], 141 | ["U", "text.roff", "constant.character.escape.misc.roff"] 142 | ],[ 143 | ["U", "text.roff"] 144 | ],[ 145 | ["", "text.roff"] 146 | ],[ 147 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 148 | ["BI", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 149 | [" ", "text.roff", "markup.bold.roff"], 150 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 151 | ["BBBBBBB", "text.roff", "markup.bold.roff"], 152 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 153 | [" ", "text.roff", "markup.bold.roff"], 154 | ["III", "text.roff", "markup.italic.roff"], 155 | [" ", "text.roff", "markup.bold.roff"], 156 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 157 | ["BBBBB BBBB", "text.roff", "markup.bold.roff"], 158 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 159 | [" ", "text.roff", "markup.bold.roff"], 160 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 161 | ],[ 162 | [" ", "text.roff", "constant.character.escape.newline.roff"], 163 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.begin.roff"], 164 | ["IIII III", "text.roff", "markup.italic.roff"], 165 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 166 | ],[ 167 | ["IIIIII ", "text.roff", "markup.italic.roff"], 168 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.end.roff"], 169 | [" ", "text.roff", "markup.bold.roff"], 170 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 171 | ["BBB", "text.roff", "markup.bold.roff"], 172 | [" ", "text.roff", "markup.bold.roff"] 173 | ],[ 174 | ["UU", "text.roff"] 175 | ]] -------------------------------------------------------------------------------- /spec/fixtures/output/font-BI.3.json: -------------------------------------------------------------------------------- 1 | [[ 2 | [".", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "punctuation.definition.macro.roff"], 3 | ["TH", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "entity.name.function.roff"] 4 | ],[ 5 | ["", "text.roff"] 6 | ],[ 7 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 8 | ["BI", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 9 | [" ", "text.roff", "markup.bold.roff"], 10 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 11 | ["BBBBBBB", "text.roff", "markup.bold.roff"], 12 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 13 | [" ", "text.roff", "markup.bold.roff"], 14 | ["IIIIII", "text.roff", "markup.italic.roff"], 15 | [" ", "text.roff", "markup.bold.roff"], 16 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 17 | ["", "text.roff", "markup.bold.roff"] 18 | ],[ 19 | ["BBBBBB", "text.roff", "markup.italic.roff"], 20 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 21 | ],[ 22 | ["BBBBBB", "text.roff", "markup.italic.roff"], 23 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 24 | ],[ 25 | ["BBB", "text.roff", "markup.italic.roff"], 26 | [" ", "text.roff", "markup.bold.roff"], 27 | ["III", "text.roff", "markup.bold.roff"] 28 | ],[ 29 | ["", "text.roff"] 30 | ],[ 31 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 32 | ["BI", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 33 | [" ", "text.roff", "markup.bold.roff"], 34 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 35 | ["BBBBBBB", "text.roff", "markup.bold.roff"], 36 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 37 | [" ", "text.roff", "markup.bold.roff"], 38 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.begin.roff"], 39 | ["IIIIII", "text.roff", "markup.italic.roff"], 40 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.end.roff"], 41 | [" ", "text.roff", "markup.bold.roff"], 42 | ["BBBBB", "text.roff", "markup.bold.roff"], 43 | [" ", "text.roff", "markup.bold.roff"], 44 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 45 | ],[ 46 | ["IIIIII", "text.roff", "markup.italic.roff"], 47 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 48 | ],[ 49 | ["IIIIII", "text.roff", "markup.italic.roff"], 50 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 51 | ],[ 52 | ["III", "text.roff", "markup.italic.roff"], 53 | [" ", "text.roff", "markup.bold.roff"], 54 | ["BBB", "text.roff", "markup.bold.roff"] 55 | ]] -------------------------------------------------------------------------------- /spec/fixtures/output/font-BR.1.json: -------------------------------------------------------------------------------- 1 | [[ 2 | [".", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "punctuation.definition.macro.roff"], 3 | ["TH", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "entity.name.function.roff"] 4 | ],[ 5 | ["", "text.roff"] 6 | ],[ 7 | ["", "text.roff"] 8 | ],[ 9 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 10 | ["BR", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 11 | [" ", "text.roff", "markup.bold.roff"], 12 | ["BBBBBB", "text.roff", "markup.bold.roff"], 13 | [" ", "text.roff", "markup.bold.roff"], 14 | ["RRRR", "text.roff", "markup.plain.roff"], 15 | [" ", "text.roff", "markup.bold.roff"], 16 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 17 | ["", "text.roff", "markup.bold.roff"] 18 | ],[ 19 | [" ", "text.roff", "markup.bold.roff"], 20 | ["BBBBB", "text.roff", "markup.bold.roff"], 21 | [" ", "text.roff", "markup.bold.roff"], 22 | ["RRR", "text.roff", "markup.plain.roff"], 23 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 24 | ],[ 25 | ["RRR", "text.roff", "markup.plain.roff"], 26 | [" ", "text.roff", "markup.bold.roff"], 27 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 28 | ["", "text.roff", "markup.bold.roff"] 29 | ],[ 30 | [" ", "text.roff", "markup.bold.roff"], 31 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 32 | ["", "text.roff", "markup.bold.roff"] 33 | ],[ 34 | [" ", "text.roff", "markup.bold.roff"], 35 | ["BBB", "text.roff", "markup.bold.roff"], 36 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 37 | ],[ 38 | ["BBBB", "text.roff", "markup.bold.roff"], 39 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 40 | ],[ 41 | ["BB", "text.roff", "markup.bold.roff"], 42 | [" ", "text.roff", "markup.bold.roff"], 43 | ["RRR", "text.roff", "markup.plain.roff"], 44 | [" ", "text.roff", "markup.bold.roff"], 45 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 46 | ["", "text.roff", "markup.bold.roff"] 47 | ],[ 48 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 49 | ],[ 50 | ["B", "text.roff", "markup.plain.roff"], 51 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.space.roff", "punctuation.definition.escape.roff"], 52 | [" ", "text.roff", "markup.plain.roff", "constant.character.escape.space.roff"], 53 | ["BB", "text.roff", "markup.plain.roff"] 54 | ],[ 55 | ["", "text.roff"] 56 | ],[ 57 | ["\\\"", "text.roff", "comment.line.roff", "punctuation.definition.comment.roff"], 58 | [" Comment Comment\\", "text.roff", "comment.line.roff"] 59 | ],[ 60 | ["UUUUUU UUUUUUUU", "text.roff"] 61 | ],[ 62 | ["", "text.roff"] 63 | ],[ 64 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 65 | ["BR", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 66 | [" ", "text.roff", "markup.bold.roff"], 67 | ["BBBBBB", "text.roff", "markup.bold.roff"], 68 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 69 | ],[ 70 | [" ", "text.roff", "markup.bold.roff"], 71 | ["RRRR", "text.roff", "markup.plain.roff"], 72 | [" ", "text.roff", "markup.bold.roff"], 73 | ["BBBBBB", "text.roff", "markup.bold.roff"], 74 | [" ", "text.roff", "markup.bold.roff"], 75 | ["RRRRR", "text.roff", "markup.plain.roff"], 76 | ["\\", "text.roff", "markup.plain.roff", "punctuation.definition.concealed.escape.backslash.roff"], 77 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "entity.name.function.roff", "punctuation.definition.escape.roff"], 78 | ["R", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "entity.name.function.roff"], 79 | ["R", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "string.other.roff", "punctuation.definition.begin.roff"], 80 | ["R", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "string.other.roff", "punctuation.definition.end.roff"], 81 | ["R", "text.roff", "markup.plain.roff"], 82 | ["\"", "text.roff", "markup.plain.roff"], 83 | [" ", "text.roff", "markup.bold.roff"], 84 | ["BBBBB", "text.roff", "markup.bold.roff"], 85 | [" ", "text.roff", "markup.bold.roff"], 86 | ["RRRRRRRRR", "text.roff", "markup.plain.roff"], 87 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 88 | ],[ 89 | ["\\", "text.roff", "markup.plain.roff", "punctuation.definition.concealed.escape.backslash.roff"], 90 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "entity.name.function.roff", "punctuation.definition.escape.roff"], 91 | ["R", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "entity.name.function.roff"], 92 | ["R", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "string.other.roff", "punctuation.definition.begin.roff"], 93 | ["R", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "string.other.roff", "punctuation.definition.end.roff"], 94 | ["RRR", "text.roff", "markup.plain.roff"], 95 | [" ", "text.roff", "markup.bold.roff"], 96 | ["BBBBBBBB", "text.roff", "markup.bold.roff"] 97 | ]] -------------------------------------------------------------------------------- /spec/fixtures/output/font-BR.2.json: -------------------------------------------------------------------------------- 1 | [[ 2 | [".", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "punctuation.definition.macro.roff"], 3 | ["TH", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "entity.name.function.roff"] 4 | ],[ 5 | ["", "text.roff"] 6 | ],[ 7 | [".", "text.roff", "comment.line.roff", "punctuation.definition.comment.roff"], 8 | ["\\\"", "text.roff", "comment.line.roff", "punctuation.definition.comment.roff"], 9 | [" EDGE-CASE ISSUE:", "text.roff", "comment.line.roff"] 10 | ],[ 11 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 12 | ["BR", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 13 | [" ", "text.roff", "markup.bold.roff"], 14 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 15 | ["BBBBBBB", "text.roff", "markup.bold.roff"], 16 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 17 | [" ", "text.roff", "markup.bold.roff"], 18 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 19 | ["RRRRRR", "text.roff", "markup.plain.roff"], 20 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.end.roff"], 21 | ["BBBB\\", "text.roff", "markup.bold.roff"], 22 | ["", "text.roff"] 23 | ],[ 24 | ["UUUUUU \"UUU\"UU UUUU", "text.roff"] 25 | ],[ 26 | ["", "text.roff"] 27 | ],[ 28 | [".", "text.roff", "comment.line.roff", "punctuation.definition.comment.roff"], 29 | ["\\\"", "text.roff", "comment.line.roff", "punctuation.definition.comment.roff"], 30 | [" This works, though:", "text.roff", "comment.line.roff"] 31 | ],[ 32 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 33 | ["BR", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 34 | [" ", "text.roff", "markup.bold.roff"], 35 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 36 | ["BBBBBBB", "text.roff", "markup.bold.roff"], 37 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 38 | [" ", "text.roff", "markup.bold.roff"], 39 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 40 | ["RRRRRR", "text.roff", "markup.plain.roff"], 41 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.end.roff"], 42 | [" ", "text.roff", "markup.bold.roff"], 43 | ["BBBB", "text.roff", "markup.bold.roff"], 44 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 45 | ],[ 46 | ["BBBBBB", "text.roff", "markup.bold.roff"], 47 | [" ", "text.roff", "markup.bold.roff"], 48 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 49 | ["RRR", "text.roff", "markup.plain.roff"], 50 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.end.roff"], 51 | ["BB ", "text.roff", "markup.bold.roff"], 52 | ["RRRR", "text.roff", "markup.plain.roff"] 53 | ],[ 54 | ["", "text.roff"] 55 | ],[ 56 | ["", "text.roff"] 57 | ],[ 58 | ["", "text.roff"] 59 | ],[ 60 | ["", "text.roff"] 61 | ],[ 62 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 63 | ["BR", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 64 | [" ", "text.roff", "markup.bold.roff"], 65 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 66 | ["BBBBBBB", "text.roff", "markup.bold.roff"], 67 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 68 | [" ", "text.roff", "markup.bold.roff"], 69 | ["RRR", "text.roff", "markup.plain.roff"], 70 | [" ", "text.roff", "markup.bold.roff"], 71 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 72 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 73 | [" ", "text.roff", "markup.bold.roff"], 74 | ["RR", "text.roff", "markup.plain.roff"], 75 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff", "punctuation.definition.escape.roff"], 76 | ["n", "text.roff", "markup.plain.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff"], 77 | ["(", "text.roff", "markup.plain.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff", "punctuation.definition.brace.roff"], 78 | ["aa", "text.roff", "markup.plain.roff", "constant.character.escape.function.expand-register.roff", "variable.parameter.roff"], 79 | ["RR", "text.roff", "markup.plain.roff"], 80 | [" ", "text.roff", "markup.bold.roff"], 81 | ["BBBB", "text.roff", "markup.bold.roff"], 82 | ["\"", "text.roff", "markup.bold.roff"], 83 | [" ", "text.roff", "markup.bold.roff"], 84 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 85 | ],[ 86 | [" ", "text.roff", "constant.character.escape.newline.roff"], 87 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 88 | ["RR", "text.roff", "markup.plain.roff"], 89 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff", "punctuation.definition.escape.roff"], 90 | ["n", "text.roff", "markup.plain.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff"], 91 | ["(", "text.roff", "markup.plain.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff", "punctuation.definition.brace.roff"], 92 | ["aa", "text.roff", "markup.plain.roff", "constant.character.escape.function.expand-register.roff", "variable.parameter.roff"], 93 | ["RR R", "text.roff", "markup.plain.roff"], 94 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff", "punctuation.definition.escape.roff"], 95 | ["n", "text.roff", "markup.plain.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff"], 96 | ["(", "text.roff", "markup.plain.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff", "punctuation.definition.brace.roff"], 97 | ["aa", "text.roff", "markup.plain.roff", "constant.character.escape.function.expand-register.roff", "variable.parameter.roff"], 98 | ["R", "text.roff", "markup.plain.roff"] 99 | ],[ 100 | ["UUUUUU \" \"UUU ", "text.roff"] 101 | ],[ 102 | ["UU", "text.roff"] 103 | ],[ 104 | ["", "text.roff"] 105 | ],[ 106 | ["", "text.roff"] 107 | ],[ 108 | ["", "text.roff"] 109 | ],[ 110 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 111 | ["BR", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 112 | [" ", "text.roff", "markup.bold.roff"], 113 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 114 | ["BBBBBBB", "text.roff", "markup.bold.roff"], 115 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 116 | ["RRR", "text.roff", "markup.plain.roff"], 117 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "entity.name.function.roff", "punctuation.definition.escape.roff"], 118 | ["R", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "entity.name.function.roff"], 119 | ["R", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "string.other.roff", "punctuation.definition.begin.roff"], 120 | ["R", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "string.other.roff", "punctuation.definition.end.roff"], 121 | ["\"", "text.roff", "markup.plain.roff"], 122 | [" ", "text.roff", "markup.bold.roff"], 123 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 124 | ["", "text.roff", "markup.bold.roff"] 125 | ],[ 126 | [" ", "text.roff", "markup.bold.roff"], 127 | ["BBBBB", "text.roff", "markup.bold.roff"], 128 | [" ", "text.roff", "markup.bold.roff"], 129 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 130 | ["RRRRR RRR", "text.roff", "markup.plain.roff"], 131 | ["R", "text.roff", "markup.plain.roff"] 132 | ],[ 133 | ["", "text.roff"] 134 | ],[ 135 | ["UUU", "text.roff"] 136 | ],[ 137 | ["\" UUUU \"UUU", "text.roff"], 138 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 139 | ],[ 140 | ["UUUUUUUUUU UUU ", "text.roff"], 141 | ["\\", "text.roff", "constant.character.escape.misc.roff", "punctuation.definition.escape.roff"], 142 | ["U", "text.roff", "constant.character.escape.misc.roff"] 143 | ],[ 144 | ["U", "text.roff"] 145 | ],[ 146 | ["", "text.roff"] 147 | ],[ 148 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 149 | ["BR", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 150 | [" ", "text.roff", "markup.bold.roff"], 151 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 152 | ["BBBBBBB", "text.roff", "markup.bold.roff"], 153 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 154 | [" ", "text.roff", "markup.bold.roff"], 155 | ["RRR", "text.roff", "markup.plain.roff"], 156 | [" ", "text.roff", "markup.bold.roff"], 157 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 158 | ["BBBBB BBBB", "text.roff", "markup.bold.roff"], 159 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 160 | [" ", "text.roff", "markup.bold.roff"], 161 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 162 | ],[ 163 | [" ", "text.roff", "constant.character.escape.newline.roff"], 164 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 165 | ["RRRR RRR", "text.roff", "markup.plain.roff"], 166 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 167 | ],[ 168 | ["RRRRRR ", "text.roff", "markup.plain.roff"], 169 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.end.roff"], 170 | [" ", "text.roff", "markup.bold.roff"], 171 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 172 | ["BBB", "text.roff", "markup.bold.roff"], 173 | [" ", "text.roff", "markup.bold.roff"] 174 | ],[ 175 | ["UU", "text.roff"] 176 | ]] -------------------------------------------------------------------------------- /spec/fixtures/output/font-BR.3.json: -------------------------------------------------------------------------------- 1 | [[ 2 | [".", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "punctuation.definition.macro.roff"], 3 | ["TH", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "entity.name.function.roff"] 4 | ],[ 5 | ["", "text.roff"] 6 | ],[ 7 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 8 | ["BR", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 9 | [" ", "text.roff", "markup.bold.roff"], 10 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 11 | ["BBBBBBB", "text.roff", "markup.bold.roff"], 12 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 13 | [" ", "text.roff", "markup.bold.roff"], 14 | ["RRRRRR", "text.roff", "markup.plain.roff"], 15 | [" ", "text.roff", "markup.bold.roff"], 16 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 17 | ["", "text.roff", "markup.bold.roff"] 18 | ],[ 19 | ["BBBBBB", "text.roff", "markup.plain.roff"], 20 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 21 | ],[ 22 | ["BBBBBB", "text.roff", "markup.plain.roff"], 23 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 24 | ],[ 25 | ["BBB", "text.roff", "markup.plain.roff"], 26 | [" ", "text.roff", "markup.bold.roff"], 27 | ["RRR", "text.roff", "markup.bold.roff"] 28 | ],[ 29 | ["", "text.roff"] 30 | ],[ 31 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 32 | ["BR", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 33 | [" ", "text.roff", "markup.bold.roff"], 34 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 35 | ["BBBBBBB", "text.roff", "markup.bold.roff"], 36 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 37 | [" ", "text.roff", "markup.bold.roff"], 38 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 39 | ["RRRRRR", "text.roff", "markup.plain.roff"], 40 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.end.roff"], 41 | [" ", "text.roff", "markup.bold.roff"], 42 | ["BBBBB", "text.roff", "markup.bold.roff"], 43 | [" ", "text.roff", "markup.bold.roff"], 44 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 45 | ],[ 46 | ["RRRRRR", "text.roff", "markup.plain.roff"], 47 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 48 | ],[ 49 | ["RRRRRR", "text.roff", "markup.plain.roff"], 50 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 51 | ],[ 52 | ["RRR", "text.roff", "markup.plain.roff"], 53 | [" ", "text.roff", "markup.bold.roff"], 54 | ["BBB", "text.roff", "markup.bold.roff"] 55 | ]] -------------------------------------------------------------------------------- /spec/fixtures/output/font-IB.1.json: -------------------------------------------------------------------------------- 1 | [[ 2 | [".", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "punctuation.definition.macro.roff"], 3 | ["TH", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "entity.name.function.roff"] 4 | ],[ 5 | ["", "text.roff"] 6 | ],[ 7 | ["", "text.roff"] 8 | ],[ 9 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 10 | ["IB", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 11 | [" ", "text.roff", "markup.italic.roff"], 12 | ["IIIIII", "text.roff", "markup.italic.roff"], 13 | [" ", "text.roff", "markup.italic.roff"], 14 | ["BBBB", "text.roff", "markup.bold.roff"], 15 | [" ", "text.roff", "markup.italic.roff"], 16 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 17 | ["", "text.roff", "markup.italic.roff"] 18 | ],[ 19 | [" ", "text.roff", "markup.italic.roff"], 20 | ["IIIII", "text.roff", "markup.italic.roff"], 21 | [" ", "text.roff", "markup.italic.roff"], 22 | ["BBB", "text.roff", "markup.bold.roff"], 23 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 24 | ],[ 25 | ["BBB", "text.roff", "markup.bold.roff"], 26 | [" ", "text.roff", "markup.italic.roff"], 27 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 28 | ["", "text.roff", "markup.italic.roff"] 29 | ],[ 30 | [" ", "text.roff", "markup.italic.roff"], 31 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 32 | ["", "text.roff", "markup.italic.roff"] 33 | ],[ 34 | [" ", "text.roff", "markup.italic.roff"], 35 | ["III", "text.roff", "markup.italic.roff"], 36 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 37 | ],[ 38 | ["IIII", "text.roff", "markup.italic.roff"], 39 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 40 | ],[ 41 | ["II", "text.roff", "markup.italic.roff"], 42 | [" ", "text.roff", "markup.italic.roff"], 43 | ["BBB", "text.roff", "markup.bold.roff"], 44 | [" ", "text.roff", "markup.italic.roff"], 45 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 46 | ["", "text.roff", "markup.italic.roff"] 47 | ],[ 48 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 49 | ],[ 50 | ["I", "text.roff", "markup.bold.roff"], 51 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.space.roff", "punctuation.definition.escape.roff"], 52 | [" ", "text.roff", "markup.bold.roff", "constant.character.escape.space.roff"], 53 | ["II", "text.roff", "markup.bold.roff"] 54 | ],[ 55 | ["", "text.roff"] 56 | ],[ 57 | ["\\\"", "text.roff", "comment.line.roff", "punctuation.definition.comment.roff"], 58 | [" Comment Comment\\", "text.roff", "comment.line.roff"] 59 | ],[ 60 | ["UUUUUU UUUUUUUU", "text.roff"] 61 | ],[ 62 | ["", "text.roff"] 63 | ],[ 64 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 65 | ["IB", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 66 | [" ", "text.roff", "markup.italic.roff"], 67 | ["IIIIII", "text.roff", "markup.italic.roff"], 68 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 69 | ],[ 70 | [" ", "text.roff", "markup.italic.roff"], 71 | ["BBBB", "text.roff", "markup.bold.roff"], 72 | [" ", "text.roff", "markup.italic.roff"], 73 | ["IIIIII", "text.roff", "markup.italic.roff"], 74 | [" ", "text.roff", "markup.italic.roff"], 75 | ["BBBBB", "text.roff", "markup.bold.roff"], 76 | ["\\", "text.roff", "markup.bold.roff", "punctuation.definition.concealed.escape.backslash.roff"], 77 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.function.check-identifier.gnu.roff", "entity.name.function.roff", "punctuation.definition.escape.roff"], 78 | ["B", "text.roff", "markup.bold.roff", "constant.character.escape.function.check-identifier.gnu.roff", "entity.name.function.roff"], 79 | ["B", "text.roff", "markup.bold.roff", "constant.character.escape.function.check-identifier.gnu.roff", "string.other.roff", "punctuation.definition.begin.roff"], 80 | ["B", "text.roff", "markup.bold.roff", "constant.character.escape.function.check-identifier.gnu.roff", "string.other.roff", "punctuation.definition.end.roff"], 81 | ["B", "text.roff", "markup.bold.roff"], 82 | ["\"", "text.roff", "markup.bold.roff"], 83 | [" ", "text.roff", "markup.italic.roff"], 84 | ["IIIII", "text.roff", "markup.italic.roff"], 85 | [" ", "text.roff", "markup.italic.roff"], 86 | ["BBBBBBBBB", "text.roff", "markup.bold.roff"], 87 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 88 | ],[ 89 | ["\\", "text.roff", "markup.bold.roff", "punctuation.definition.concealed.escape.backslash.roff"], 90 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.function.check-identifier.gnu.roff", "entity.name.function.roff", "punctuation.definition.escape.roff"], 91 | ["B", "text.roff", "markup.bold.roff", "constant.character.escape.function.check-identifier.gnu.roff", "entity.name.function.roff"], 92 | ["B", "text.roff", "markup.bold.roff", "constant.character.escape.function.check-identifier.gnu.roff", "string.other.roff", "punctuation.definition.begin.roff"], 93 | ["B", "text.roff", "markup.bold.roff", "constant.character.escape.function.check-identifier.gnu.roff", "string.other.roff", "punctuation.definition.end.roff"], 94 | ["BBB", "text.roff", "markup.bold.roff"], 95 | [" ", "text.roff", "markup.italic.roff"], 96 | ["IIIIIIII", "text.roff", "markup.italic.roff"] 97 | ]] -------------------------------------------------------------------------------- /spec/fixtures/output/font-IB.3.json: -------------------------------------------------------------------------------- 1 | [[ 2 | [".", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "punctuation.definition.macro.roff"], 3 | ["TH", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "entity.name.function.roff"] 4 | ],[ 5 | ["", "text.roff"] 6 | ],[ 7 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 8 | ["IB", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 9 | [" ", "text.roff", "markup.italic.roff"], 10 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.begin.roff"], 11 | ["IIIIIII", "text.roff", "markup.italic.roff"], 12 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.end.roff"], 13 | [" ", "text.roff", "markup.italic.roff"], 14 | ["BBBBBB", "text.roff", "markup.bold.roff"], 15 | [" ", "text.roff", "markup.italic.roff"], 16 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 17 | ["", "text.roff", "markup.italic.roff"] 18 | ],[ 19 | ["IIIIII", "text.roff", "markup.bold.roff"], 20 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 21 | ],[ 22 | ["IIIIII", "text.roff", "markup.bold.roff"], 23 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 24 | ],[ 25 | ["III", "text.roff", "markup.bold.roff"], 26 | [" ", "text.roff", "markup.italic.roff"], 27 | ["BBB", "text.roff", "markup.italic.roff"] 28 | ],[ 29 | ["", "text.roff"] 30 | ],[ 31 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 32 | ["IB", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 33 | [" ", "text.roff", "markup.italic.roff"], 34 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.begin.roff"], 35 | ["IIIIIII", "text.roff", "markup.italic.roff"], 36 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.end.roff"], 37 | [" ", "text.roff", "markup.italic.roff"], 38 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 39 | ["BBBBBB", "text.roff", "markup.bold.roff"], 40 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 41 | [" ", "text.roff", "markup.italic.roff"], 42 | ["IIIII", "text.roff", "markup.italic.roff"], 43 | [" ", "text.roff", "markup.italic.roff"], 44 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 45 | ],[ 46 | ["BBBBBB", "text.roff", "markup.bold.roff"], 47 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 48 | ],[ 49 | ["BBBBBB", "text.roff", "markup.bold.roff"], 50 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 51 | ],[ 52 | ["BBB", "text.roff", "markup.bold.roff"], 53 | [" ", "text.roff", "markup.italic.roff"], 54 | ["III", "text.roff", "markup.italic.roff"] 55 | ]] -------------------------------------------------------------------------------- /spec/fixtures/output/font-IR.1.json: -------------------------------------------------------------------------------- 1 | [[ 2 | [".", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "punctuation.definition.macro.roff"], 3 | ["TH", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "entity.name.function.roff"] 4 | ],[ 5 | ["", "text.roff"] 6 | ],[ 7 | ["", "text.roff"] 8 | ],[ 9 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 10 | ["IR", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 11 | [" ", "text.roff", "markup.italic.roff"], 12 | ["IIIIII", "text.roff", "markup.italic.roff"], 13 | [" ", "text.roff", "markup.italic.roff"], 14 | ["RRRR", "text.roff", "markup.plain.roff"], 15 | [" ", "text.roff", "markup.italic.roff"], 16 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 17 | ["", "text.roff", "markup.italic.roff"] 18 | ],[ 19 | [" ", "text.roff", "markup.italic.roff"], 20 | ["IIIII", "text.roff", "markup.italic.roff"], 21 | [" ", "text.roff", "markup.italic.roff"], 22 | ["RRR", "text.roff", "markup.plain.roff"], 23 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 24 | ],[ 25 | ["RRR", "text.roff", "markup.plain.roff"], 26 | [" ", "text.roff", "markup.italic.roff"], 27 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 28 | ["", "text.roff", "markup.italic.roff"] 29 | ],[ 30 | [" ", "text.roff", "markup.italic.roff"], 31 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 32 | ["", "text.roff", "markup.italic.roff"] 33 | ],[ 34 | [" ", "text.roff", "markup.italic.roff"], 35 | ["III", "text.roff", "markup.italic.roff"], 36 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 37 | ],[ 38 | ["IIII", "text.roff", "markup.italic.roff"], 39 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 40 | ],[ 41 | ["II", "text.roff", "markup.italic.roff"], 42 | [" ", "text.roff", "markup.italic.roff"], 43 | ["RRR", "text.roff", "markup.plain.roff"], 44 | [" ", "text.roff", "markup.italic.roff"], 45 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 46 | ["", "text.roff", "markup.italic.roff"] 47 | ],[ 48 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 49 | ],[ 50 | ["I", "text.roff", "markup.plain.roff"], 51 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.space.roff", "punctuation.definition.escape.roff"], 52 | [" ", "text.roff", "markup.plain.roff", "constant.character.escape.space.roff"], 53 | ["II", "text.roff", "markup.plain.roff"] 54 | ],[ 55 | ["", "text.roff"] 56 | ],[ 57 | ["\\\"", "text.roff", "comment.line.roff", "punctuation.definition.comment.roff"], 58 | [" Comment Comment\\", "text.roff", "comment.line.roff"] 59 | ],[ 60 | ["UUUUUU UUUUUUUU", "text.roff"] 61 | ],[ 62 | ["", "text.roff"] 63 | ],[ 64 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 65 | ["IR", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 66 | [" ", "text.roff", "markup.italic.roff"], 67 | ["IIIIII", "text.roff", "markup.italic.roff"], 68 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 69 | ],[ 70 | [" ", "text.roff", "markup.italic.roff"], 71 | ["RRRR", "text.roff", "markup.plain.roff"], 72 | [" ", "text.roff", "markup.italic.roff"], 73 | ["IIIIII", "text.roff", "markup.italic.roff"], 74 | [" ", "text.roff", "markup.italic.roff"], 75 | ["RRRRR", "text.roff", "markup.plain.roff"], 76 | ["\\", "text.roff", "markup.plain.roff", "punctuation.definition.concealed.escape.backslash.roff"], 77 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "entity.name.function.roff", "punctuation.definition.escape.roff"], 78 | ["R", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "entity.name.function.roff"], 79 | ["R", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "string.other.roff", "punctuation.definition.begin.roff"], 80 | ["R", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "string.other.roff", "punctuation.definition.end.roff"], 81 | ["R", "text.roff", "markup.plain.roff"], 82 | ["\"", "text.roff", "markup.plain.roff"], 83 | [" ", "text.roff", "markup.italic.roff"], 84 | ["IIIII", "text.roff", "markup.italic.roff"], 85 | [" ", "text.roff", "markup.italic.roff"], 86 | ["RRRRRRRRR", "text.roff", "markup.plain.roff"], 87 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 88 | ],[ 89 | ["\\", "text.roff", "markup.plain.roff", "punctuation.definition.concealed.escape.backslash.roff"], 90 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "entity.name.function.roff", "punctuation.definition.escape.roff"], 91 | ["R", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "entity.name.function.roff"], 92 | ["R", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "string.other.roff", "punctuation.definition.begin.roff"], 93 | ["R", "text.roff", "markup.plain.roff", "constant.character.escape.function.check-identifier.gnu.roff", "string.other.roff", "punctuation.definition.end.roff"], 94 | ["RRR", "text.roff", "markup.plain.roff"], 95 | [" ", "text.roff", "markup.italic.roff"], 96 | ["IIIIIIII", "text.roff", "markup.italic.roff"] 97 | ]] -------------------------------------------------------------------------------- /spec/fixtures/output/font-IR.3.json: -------------------------------------------------------------------------------- 1 | [[ 2 | [".", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "punctuation.definition.macro.roff"], 3 | ["TH", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "entity.name.function.roff"] 4 | ],[ 5 | ["", "text.roff"] 6 | ],[ 7 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 8 | ["IR", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 9 | [" ", "text.roff", "markup.italic.roff"], 10 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.begin.roff"], 11 | ["IIIIIII", "text.roff", "markup.italic.roff"], 12 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.end.roff"], 13 | [" ", "text.roff", "markup.italic.roff"], 14 | ["RRRRRR", "text.roff", "markup.plain.roff"], 15 | [" ", "text.roff", "markup.italic.roff"], 16 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 17 | ["", "text.roff", "markup.italic.roff"] 18 | ],[ 19 | ["IIIIII", "text.roff", "markup.plain.roff"], 20 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 21 | ],[ 22 | ["IIIIII", "text.roff", "markup.plain.roff"], 23 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 24 | ],[ 25 | ["III", "text.roff", "markup.plain.roff"], 26 | [" ", "text.roff", "markup.italic.roff"], 27 | ["RRR", "text.roff", "markup.italic.roff"] 28 | ],[ 29 | ["", "text.roff"] 30 | ],[ 31 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 32 | ["IR", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 33 | [" ", "text.roff", "markup.italic.roff"], 34 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.begin.roff"], 35 | ["IIIIIII", "text.roff", "markup.italic.roff"], 36 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.end.roff"], 37 | [" ", "text.roff", "markup.italic.roff"], 38 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 39 | ["RRRRRR", "text.roff", "markup.plain.roff"], 40 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.end.roff"], 41 | [" ", "text.roff", "markup.italic.roff"], 42 | ["IIIII", "text.roff", "markup.italic.roff"], 43 | [" ", "text.roff", "markup.italic.roff"], 44 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 45 | ],[ 46 | ["RRRRRR", "text.roff", "markup.plain.roff"], 47 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 48 | ],[ 49 | ["RRRRRR", "text.roff", "markup.plain.roff"], 50 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 51 | ],[ 52 | ["RRR", "text.roff", "markup.plain.roff"], 53 | [" ", "text.roff", "markup.italic.roff"], 54 | ["III", "text.roff", "markup.italic.roff"] 55 | ]] -------------------------------------------------------------------------------- /spec/fixtures/output/font-RB.1.json: -------------------------------------------------------------------------------- 1 | [[ 2 | [".", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "punctuation.definition.macro.roff"], 3 | ["TH", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "entity.name.function.roff"] 4 | ],[ 5 | ["", "text.roff"] 6 | ],[ 7 | ["", "text.roff"] 8 | ],[ 9 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 10 | ["RB", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 11 | [" ", "text.roff", "markup.plain.roff"], 12 | ["RRRRRR", "text.roff", "markup.plain.roff"], 13 | [" ", "text.roff", "markup.plain.roff"], 14 | ["BBBB", "text.roff", "markup.bold.roff"], 15 | [" ", "text.roff", "markup.plain.roff"], 16 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 17 | ["", "text.roff", "markup.plain.roff"] 18 | ],[ 19 | [" ", "text.roff", "markup.plain.roff"], 20 | ["RRRRR", "text.roff", "markup.plain.roff"], 21 | [" ", "text.roff", "markup.plain.roff"], 22 | ["BBB", "text.roff", "markup.bold.roff"], 23 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 24 | ],[ 25 | ["BBB", "text.roff", "markup.bold.roff"], 26 | [" ", "text.roff", "markup.plain.roff"], 27 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 28 | ["", "text.roff", "markup.plain.roff"] 29 | ],[ 30 | [" ", "text.roff", "markup.plain.roff"], 31 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 32 | ["", "text.roff", "markup.plain.roff"] 33 | ],[ 34 | [" ", "text.roff", "markup.plain.roff"], 35 | ["RRR", "text.roff", "markup.plain.roff"], 36 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 37 | ],[ 38 | ["RRRR", "text.roff", "markup.plain.roff"], 39 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 40 | ],[ 41 | ["RR", "text.roff", "markup.plain.roff"], 42 | [" ", "text.roff", "markup.plain.roff"], 43 | ["BBB", "text.roff", "markup.bold.roff"], 44 | [" ", "text.roff", "markup.plain.roff"], 45 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 46 | ["", "text.roff", "markup.plain.roff"] 47 | ],[ 48 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 49 | ],[ 50 | ["R", "text.roff", "markup.bold.roff"], 51 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.space.roff", "punctuation.definition.escape.roff"], 52 | [" ", "text.roff", "markup.bold.roff", "constant.character.escape.space.roff"], 53 | ["RR", "text.roff", "markup.bold.roff"] 54 | ],[ 55 | ["", "text.roff"] 56 | ],[ 57 | ["\\\"", "text.roff", "comment.line.roff", "punctuation.definition.comment.roff"], 58 | [" Comment Comment\\", "text.roff", "comment.line.roff"] 59 | ],[ 60 | ["UUUUUU UUUUUUUU", "text.roff"] 61 | ],[ 62 | ["", "text.roff"] 63 | ],[ 64 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 65 | ["RB", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 66 | [" ", "text.roff", "markup.plain.roff"], 67 | ["RRRRRR", "text.roff", "markup.plain.roff"], 68 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 69 | ],[ 70 | [" ", "text.roff", "markup.plain.roff"], 71 | ["BBBB", "text.roff", "markup.bold.roff"], 72 | [" ", "text.roff", "markup.plain.roff"], 73 | ["RRRRRR", "text.roff", "markup.plain.roff"], 74 | [" ", "text.roff", "markup.plain.roff"], 75 | ["BBBBB", "text.roff", "markup.bold.roff"], 76 | ["\\", "text.roff", "markup.bold.roff", "punctuation.definition.concealed.escape.backslash.roff"], 77 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.function.check-identifier.gnu.roff", "entity.name.function.roff", "punctuation.definition.escape.roff"], 78 | ["B", "text.roff", "markup.bold.roff", "constant.character.escape.function.check-identifier.gnu.roff", "entity.name.function.roff"], 79 | ["B", "text.roff", "markup.bold.roff", "constant.character.escape.function.check-identifier.gnu.roff", "string.other.roff", "punctuation.definition.begin.roff"], 80 | ["B", "text.roff", "markup.bold.roff", "constant.character.escape.function.check-identifier.gnu.roff", "string.other.roff", "punctuation.definition.end.roff"], 81 | ["B", "text.roff", "markup.bold.roff"], 82 | ["\"", "text.roff", "markup.bold.roff"], 83 | [" ", "text.roff", "markup.plain.roff"], 84 | ["RRRRR", "text.roff", "markup.plain.roff"], 85 | [" ", "text.roff", "markup.plain.roff"], 86 | ["BBBBBBBBB", "text.roff", "markup.bold.roff"], 87 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 88 | ],[ 89 | ["\\", "text.roff", "markup.bold.roff", "punctuation.definition.concealed.escape.backslash.roff"], 90 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.function.check-identifier.gnu.roff", "entity.name.function.roff", "punctuation.definition.escape.roff"], 91 | ["B", "text.roff", "markup.bold.roff", "constant.character.escape.function.check-identifier.gnu.roff", "entity.name.function.roff"], 92 | ["B", "text.roff", "markup.bold.roff", "constant.character.escape.function.check-identifier.gnu.roff", "string.other.roff", "punctuation.definition.begin.roff"], 93 | ["B", "text.roff", "markup.bold.roff", "constant.character.escape.function.check-identifier.gnu.roff", "string.other.roff", "punctuation.definition.end.roff"], 94 | ["BBB", "text.roff", "markup.bold.roff"], 95 | [" ", "text.roff", "markup.plain.roff"], 96 | ["RRRRRRRR", "text.roff", "markup.plain.roff"] 97 | ]] -------------------------------------------------------------------------------- /spec/fixtures/output/font-RB.3.json: -------------------------------------------------------------------------------- 1 | [[ 2 | [".", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "punctuation.definition.macro.roff"], 3 | ["TH", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "entity.name.function.roff"] 4 | ],[ 5 | ["", "text.roff"] 6 | ],[ 7 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 8 | ["RB", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 9 | [" ", "text.roff", "markup.plain.roff"], 10 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 11 | ["RRRRRRR", "text.roff", "markup.plain.roff"], 12 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.end.roff"], 13 | [" ", "text.roff", "markup.plain.roff"], 14 | ["BBBBBB", "text.roff", "markup.bold.roff"], 15 | [" ", "text.roff", "markup.plain.roff"], 16 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 17 | ["", "text.roff", "markup.plain.roff"] 18 | ],[ 19 | ["RRRRRR", "text.roff", "markup.bold.roff"], 20 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 21 | ],[ 22 | ["RRRRRR", "text.roff", "markup.bold.roff"], 23 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 24 | ],[ 25 | ["RRR", "text.roff", "markup.bold.roff"], 26 | [" ", "text.roff", "markup.plain.roff"], 27 | ["BBB", "text.roff", "markup.plain.roff"] 28 | ],[ 29 | ["", "text.roff"] 30 | ],[ 31 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 32 | ["RB", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 33 | [" ", "text.roff", "markup.plain.roff"], 34 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 35 | ["RRRRRRR", "text.roff", "markup.plain.roff"], 36 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.end.roff"], 37 | [" ", "text.roff", "markup.plain.roff"], 38 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.begin.roff"], 39 | ["BBBBBB", "text.roff", "markup.bold.roff"], 40 | ["\"", "text.roff", "markup.bold.roff", "punctuation.definition.string.end.roff"], 41 | [" ", "text.roff", "markup.plain.roff"], 42 | ["RRRRR", "text.roff", "markup.plain.roff"], 43 | [" ", "text.roff", "markup.plain.roff"], 44 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 45 | ],[ 46 | ["BBBBBB", "text.roff", "markup.bold.roff"], 47 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 48 | ],[ 49 | ["BBBBBB", "text.roff", "markup.bold.roff"], 50 | ["\\", "text.roff", "markup.bold.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 51 | ],[ 52 | ["BBB", "text.roff", "markup.bold.roff"], 53 | [" ", "text.roff", "markup.plain.roff"], 54 | ["RRR", "text.roff", "markup.plain.roff"] 55 | ]] -------------------------------------------------------------------------------- /spec/fixtures/output/font-RI.1.json: -------------------------------------------------------------------------------- 1 | [[ 2 | [".", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "punctuation.definition.macro.roff"], 3 | ["TH", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "entity.name.function.roff"] 4 | ],[ 5 | ["", "text.roff"] 6 | ],[ 7 | ["", "text.roff"] 8 | ],[ 9 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 10 | ["RI", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 11 | [" ", "text.roff", "markup.plain.roff"], 12 | ["RRRRRR", "text.roff", "markup.plain.roff"], 13 | [" ", "text.roff", "markup.plain.roff"], 14 | ["IIII", "text.roff", "markup.italic.roff"], 15 | [" ", "text.roff", "markup.plain.roff"], 16 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 17 | ["", "text.roff", "markup.plain.roff"] 18 | ],[ 19 | [" ", "text.roff", "markup.plain.roff"], 20 | ["RRRRR", "text.roff", "markup.plain.roff"], 21 | [" ", "text.roff", "markup.plain.roff"], 22 | ["III", "text.roff", "markup.italic.roff"], 23 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 24 | ],[ 25 | ["III", "text.roff", "markup.italic.roff"], 26 | [" ", "text.roff", "markup.plain.roff"], 27 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 28 | ["", "text.roff", "markup.plain.roff"] 29 | ],[ 30 | [" ", "text.roff", "markup.plain.roff"], 31 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 32 | ["", "text.roff", "markup.plain.roff"] 33 | ],[ 34 | [" ", "text.roff", "markup.plain.roff"], 35 | ["RRR", "text.roff", "markup.plain.roff"], 36 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 37 | ],[ 38 | ["RRRR", "text.roff", "markup.plain.roff"], 39 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 40 | ],[ 41 | ["RR", "text.roff", "markup.plain.roff"], 42 | [" ", "text.roff", "markup.plain.roff"], 43 | ["III", "text.roff", "markup.italic.roff"], 44 | [" ", "text.roff", "markup.plain.roff"], 45 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 46 | ["", "text.roff", "markup.plain.roff"] 47 | ],[ 48 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 49 | ],[ 50 | ["R", "text.roff", "markup.italic.roff"], 51 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.space.roff", "punctuation.definition.escape.roff"], 52 | [" ", "text.roff", "markup.italic.roff", "constant.character.escape.space.roff"], 53 | ["RR", "text.roff", "markup.italic.roff"] 54 | ],[ 55 | ["", "text.roff"] 56 | ],[ 57 | ["\\\"", "text.roff", "comment.line.roff", "punctuation.definition.comment.roff"], 58 | [" Comment Comment\\", "text.roff", "comment.line.roff"] 59 | ],[ 60 | ["UUUUUU UUUUUUUU", "text.roff"] 61 | ],[ 62 | ["", "text.roff"] 63 | ],[ 64 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 65 | ["RI", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 66 | [" ", "text.roff", "markup.plain.roff"], 67 | ["RRRRRR", "text.roff", "markup.plain.roff"], 68 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 69 | ],[ 70 | [" ", "text.roff", "markup.plain.roff"], 71 | ["IIII", "text.roff", "markup.italic.roff"], 72 | [" ", "text.roff", "markup.plain.roff"], 73 | ["RRRRRR", "text.roff", "markup.plain.roff"], 74 | [" ", "text.roff", "markup.plain.roff"], 75 | ["IIIII", "text.roff", "markup.italic.roff"], 76 | ["\\", "text.roff", "markup.italic.roff", "punctuation.definition.concealed.escape.backslash.roff"], 77 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.misc.roff", "punctuation.definition.escape.roff"], 78 | ["I", "text.roff", "markup.italic.roff", "constant.character.escape.misc.roff"], 79 | ["III", "text.roff", "markup.italic.roff"], 80 | ["\"", "text.roff", "markup.italic.roff"], 81 | [" ", "text.roff", "markup.plain.roff"], 82 | ["RRRRR", "text.roff", "markup.plain.roff"], 83 | [" ", "text.roff", "markup.plain.roff"], 84 | ["IIIIIIIII", "text.roff", "markup.italic.roff"], 85 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 86 | ],[ 87 | ["\\", "text.roff", "markup.italic.roff", "punctuation.definition.concealed.escape.backslash.roff"], 88 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.misc.roff", "punctuation.definition.escape.roff"], 89 | ["I", "text.roff", "markup.italic.roff", "constant.character.escape.misc.roff"], 90 | ["IIIII", "text.roff", "markup.italic.roff"], 91 | [" ", "text.roff", "markup.plain.roff"], 92 | ["RRRRRRRR", "text.roff", "markup.plain.roff"] 93 | ]] -------------------------------------------------------------------------------- /spec/fixtures/output/font-RI.2.json: -------------------------------------------------------------------------------- 1 | [[ 2 | [".", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "punctuation.definition.macro.roff"], 3 | ["TH", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "entity.name.function.roff"] 4 | ],[ 5 | ["", "text.roff"] 6 | ],[ 7 | [".", "text.roff", "comment.line.roff", "punctuation.definition.comment.roff"], 8 | ["\\\"", "text.roff", "comment.line.roff", "punctuation.definition.comment.roff"], 9 | [" EDGE-CASE ISSUE:", "text.roff", "comment.line.roff"] 10 | ],[ 11 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 12 | ["RI", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 13 | [" ", "text.roff", "markup.plain.roff"], 14 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 15 | ["RRRRRRR", "text.roff", "markup.plain.roff"], 16 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.end.roff"], 17 | [" ", "text.roff", "markup.plain.roff"], 18 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.begin.roff"], 19 | ["IIIIII", "text.roff", "markup.italic.roff"], 20 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.end.roff"], 21 | ["RRRR\\", "text.roff", "markup.plain.roff"], 22 | ["", "text.roff"] 23 | ],[ 24 | ["UUUUUU \"UUU\"UU UUUU", "text.roff"] 25 | ],[ 26 | ["", "text.roff"] 27 | ],[ 28 | [".", "text.roff", "comment.line.roff", "punctuation.definition.comment.roff"], 29 | ["\\\"", "text.roff", "comment.line.roff", "punctuation.definition.comment.roff"], 30 | [" This works, though:", "text.roff", "comment.line.roff"] 31 | ],[ 32 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 33 | ["RI", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 34 | [" ", "text.roff", "markup.plain.roff"], 35 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 36 | ["RRRRRRR", "text.roff", "markup.plain.roff"], 37 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.end.roff"], 38 | [" ", "text.roff", "markup.plain.roff"], 39 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.begin.roff"], 40 | ["IIIIII", "text.roff", "markup.italic.roff"], 41 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.end.roff"], 42 | [" ", "text.roff", "markup.plain.roff"], 43 | ["RRRR", "text.roff", "markup.plain.roff"], 44 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 45 | ],[ 46 | ["RRRRRR", "text.roff", "markup.plain.roff"], 47 | [" ", "text.roff", "markup.plain.roff"], 48 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.begin.roff"], 49 | ["III", "text.roff", "markup.italic.roff"], 50 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.end.roff"], 51 | ["RR ", "text.roff", "markup.plain.roff"], 52 | ["IIII", "text.roff", "markup.italic.roff"] 53 | ],[ 54 | ["", "text.roff"] 55 | ],[ 56 | ["", "text.roff"] 57 | ],[ 58 | ["", "text.roff"] 59 | ],[ 60 | ["", "text.roff"] 61 | ],[ 62 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 63 | ["RI", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 64 | [" ", "text.roff", "markup.plain.roff"], 65 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 66 | ["RRRRRRR", "text.roff", "markup.plain.roff"], 67 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.end.roff"], 68 | [" ", "text.roff", "markup.plain.roff"], 69 | ["III", "text.roff", "markup.italic.roff"], 70 | [" ", "text.roff", "markup.plain.roff"], 71 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 72 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.end.roff"], 73 | [" ", "text.roff", "markup.plain.roff"], 74 | ["II", "text.roff", "markup.italic.roff"], 75 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff", "punctuation.definition.escape.roff"], 76 | ["n", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff"], 77 | ["(", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff", "punctuation.definition.brace.roff"], 78 | ["aa", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "variable.parameter.roff"], 79 | ["II", "text.roff", "markup.italic.roff"], 80 | [" ", "text.roff", "markup.plain.roff"], 81 | ["RRRR", "text.roff", "markup.plain.roff"], 82 | ["\"", "text.roff", "markup.plain.roff"], 83 | [" ", "text.roff", "markup.plain.roff"], 84 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 85 | ],[ 86 | [" ", "text.roff", "constant.character.escape.newline.roff"], 87 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.begin.roff"], 88 | ["II", "text.roff", "markup.italic.roff"], 89 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff", "punctuation.definition.escape.roff"], 90 | ["n", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff"], 91 | ["(", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff", "punctuation.definition.brace.roff"], 92 | ["aa", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "variable.parameter.roff"], 93 | ["II I", "text.roff", "markup.italic.roff"], 94 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff", "punctuation.definition.escape.roff"], 95 | ["n", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff"], 96 | ["(", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "entity.name.roff", "punctuation.definition.brace.roff"], 97 | ["aa", "text.roff", "markup.italic.roff", "constant.character.escape.function.expand-register.roff", "variable.parameter.roff"], 98 | ["I", "text.roff", "markup.italic.roff"] 99 | ],[ 100 | ["UUUUUU \" \"UUU ", "text.roff"] 101 | ],[ 102 | ["UU", "text.roff"] 103 | ],[ 104 | ["", "text.roff"] 105 | ],[ 106 | ["", "text.roff"] 107 | ],[ 108 | ["", "text.roff"] 109 | ],[ 110 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 111 | ["RI", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 112 | [" ", "text.roff", "markup.plain.roff"], 113 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 114 | ["RRRRRRR", "text.roff", "markup.plain.roff"], 115 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.end.roff"], 116 | ["III", "text.roff", "markup.italic.roff"], 117 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.misc.roff", "punctuation.definition.escape.roff"], 118 | ["I", "text.roff", "markup.italic.roff", "constant.character.escape.misc.roff"], 119 | ["II", "text.roff", "markup.italic.roff"], 120 | ["\"", "text.roff", "markup.italic.roff"], 121 | [" ", "text.roff", "markup.plain.roff"], 122 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 123 | ["", "text.roff", "markup.plain.roff"] 124 | ],[ 125 | [" ", "text.roff", "markup.plain.roff"], 126 | ["RRRRR", "text.roff", "markup.plain.roff"], 127 | [" ", "text.roff", "markup.plain.roff"], 128 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.begin.roff"], 129 | ["IIIII III", "text.roff", "markup.italic.roff"], 130 | ["I", "text.roff", "markup.italic.roff"] 131 | ],[ 132 | ["", "text.roff"] 133 | ],[ 134 | ["UUU", "text.roff"] 135 | ],[ 136 | ["\" UUUU \"UUU", "text.roff"], 137 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 138 | ],[ 139 | ["UUUUUUUUUU UUU ", "text.roff"], 140 | ["\\", "text.roff", "constant.character.escape.misc.roff", "punctuation.definition.escape.roff"], 141 | ["U", "text.roff", "constant.character.escape.misc.roff"] 142 | ],[ 143 | ["U", "text.roff"] 144 | ],[ 145 | ["", "text.roff"] 146 | ],[ 147 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 148 | ["RI", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 149 | [" ", "text.roff", "markup.plain.roff"], 150 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 151 | ["RRRRRRR", "text.roff", "markup.plain.roff"], 152 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.end.roff"], 153 | [" ", "text.roff", "markup.plain.roff"], 154 | ["III", "text.roff", "markup.italic.roff"], 155 | [" ", "text.roff", "markup.plain.roff"], 156 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 157 | ["RRRRR RRRR", "text.roff", "markup.plain.roff"], 158 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.end.roff"], 159 | [" ", "text.roff", "markup.plain.roff"], 160 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 161 | ],[ 162 | [" ", "text.roff", "constant.character.escape.newline.roff"], 163 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.begin.roff"], 164 | ["IIII III", "text.roff", "markup.italic.roff"], 165 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 166 | ],[ 167 | ["IIIIII ", "text.roff", "markup.italic.roff"], 168 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.end.roff"], 169 | [" ", "text.roff", "markup.plain.roff"], 170 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 171 | ["RRR", "text.roff", "markup.plain.roff"], 172 | [" ", "text.roff", "markup.plain.roff"] 173 | ],[ 174 | ["UU", "text.roff"] 175 | ]] -------------------------------------------------------------------------------- /spec/fixtures/output/font-RI.3.json: -------------------------------------------------------------------------------- 1 | [[ 2 | [".", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "punctuation.definition.macro.roff"], 3 | ["TH", "text.roff", "markup.heading.title.function.man.macro.roff", "meta.function.man.macro.roff", "entity.name.function.roff"] 4 | ],[ 5 | ["", "text.roff"] 6 | ],[ 7 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 8 | ["RI", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 9 | [" ", "text.roff", "markup.plain.roff"], 10 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 11 | ["RRRRRRR", "text.roff", "markup.plain.roff"], 12 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.end.roff"], 13 | [" ", "text.roff", "markup.plain.roff"], 14 | ["IIIIII", "text.roff", "markup.italic.roff"], 15 | [" ", "text.roff", "markup.plain.roff"], 16 | ["\\", "text.roff", "markup.plain.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"], 17 | ["", "text.roff", "markup.plain.roff"] 18 | ],[ 19 | ["RRRRRR", "text.roff", "markup.italic.roff"], 20 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 21 | ],[ 22 | ["RRRRRR", "text.roff", "markup.italic.roff"], 23 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 24 | ],[ 25 | ["RRR", "text.roff", "markup.italic.roff"], 26 | [" ", "text.roff", "markup.plain.roff"], 27 | ["III", "text.roff", "markup.plain.roff"] 28 | ],[ 29 | ["", "text.roff"] 30 | ],[ 31 | [".", "text.roff", "meta.function.man.macro.roff", "punctuation.definition.function.macro.roff"], 32 | ["RI", "text.roff", "meta.function.man.macro.roff", "entity.name.function.roff"], 33 | [" ", "text.roff", "markup.plain.roff"], 34 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.begin.roff"], 35 | ["RRRRRRR", "text.roff", "markup.plain.roff"], 36 | ["\"", "text.roff", "markup.plain.roff", "punctuation.definition.string.end.roff"], 37 | [" ", "text.roff", "markup.plain.roff"], 38 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.begin.roff"], 39 | ["IIIIII", "text.roff", "markup.italic.roff"], 40 | ["\"", "text.roff", "markup.italic.roff", "punctuation.definition.string.end.roff"], 41 | [" ", "text.roff", "markup.plain.roff"], 42 | ["RRRRR", "text.roff", "markup.plain.roff"], 43 | [" ", "text.roff", "markup.plain.roff"], 44 | ["\\", "text.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 45 | ],[ 46 | ["IIIIII", "text.roff", "markup.italic.roff"], 47 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 48 | ],[ 49 | ["IIIIII", "text.roff", "markup.italic.roff"], 50 | ["\\", "text.roff", "markup.italic.roff", "constant.character.escape.newline.roff", "punctuation.definition.escape.roff"] 51 | ],[ 52 | ["III", "text.roff", "markup.italic.roff"], 53 | [" ", "text.roff", "markup.plain.roff"], 54 | ["RRR", "text.roff", "markup.plain.roff"] 55 | ]] -------------------------------------------------------------------------------- /spec/fixtures/prune: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | /** 3 | * @fileoverview Deletes any token snapshot that doesn't have an equivalent 4 | * fixture located under ../input/ (without the trailing `.json` suffix). 5 | * Intended to keep subdirectory clean of junk after renaming fixture files. 6 | */ 7 | "use strict"; 8 | 9 | const {existsSync, readdirSync, unlinkSync} = require("fs"); 10 | const {resolve, join, relative} = require("path"); 11 | 12 | const inputDir = resolve(__dirname, "input"); 13 | const outputDir = resolve(__dirname, "output"); 14 | const pwd = process.cwd(); 15 | const format = ["Pruning orphaned fixture: ", "\x1B[4m", null, "\x1B[24m"]; 16 | 17 | if(!process.stdout.isTTY) 18 | format[1] = format[format.length - 1] = ""; 19 | 20 | const fixtures = readdirSync(outputDir).filter(name => name.toLowerCase().endsWith(".json")); 21 | for(const name of fixtures){ 22 | const inputFile = join(inputDir, name.replace(/\.json$/i, "")); 23 | if(!existsSync(inputFile)){ 24 | const outputFile = resolve(join(outputDir, name)); 25 | format[2] = relative(pwd, outputFile).replace(/^(?!\.\/)/, "./"); 26 | process.stdout.write(format.join("") + "\n"); 27 | unlinkSync(outputFile); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /spec/fixtures/update: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | /** 3 | * @fileoverview Tokenises each file named on the command-line and 4 | * writes the tokenised lines to a JSON file in the same directory 5 | * (with a `.json` suffix appended): 6 | * 7 | * $ update ./foo.1 => ./foo.1.json 8 | * $ update ./input/* && mv input/*.json ./output 9 | * 10 | * However, the quickest (and recommended) way to regenerate every 11 | * fixture is by running `npm run update-fixtures` instead. 12 | */ 13 | "use strict"; 14 | 15 | const {readdirSync, readFileSync, realpathSync, writeFileSync} = require("fs"); 16 | const {basename, extname, join, resolve} = require("path"); 17 | const FirstMate = require("first-mate"); 18 | 19 | const {GrammarRegistry} = FirstMate; 20 | const registry = new GrammarRegistry(); 21 | loadGrammarDir(resolve(__dirname, "../../grammars")); 22 | loadGrammarDir(resolve(__dirname, "../../node_modules/language-hyperlink/grammars")); 23 | 24 | const argv = process.argv.slice(2); 25 | if(!argv.length){ 26 | console.error(`Usage: ${process.argv0} ...files`); 27 | process.exit(1); 28 | } 29 | for(let path of argv){ 30 | path = realpathSync(path); 31 | const grammar = getGrammarForFile(path); 32 | if(!grammar){ 33 | console.warn(`No grammar found for ${path}`); 34 | continue; 35 | } 36 | const input = readFileSync(path, "utf8").trim(); 37 | const output = stringifyTokens(grammar.tokenizeLines(input)); 38 | writeFileSync(resolve(__dirname, path + ".json"), output, "utf8"); 39 | } 40 | 41 | 42 | /** 43 | * Return the first loaded {@link Grammar} that recognises a path/filename. 44 | * @param {String} path 45 | * @return {?Grammar} 46 | * @internal 47 | */ 48 | function getGrammarForFile(path){ 49 | if(basename(path).startsWith("ditroff.")) 50 | return registry.grammarForScopeName("source.ditroff"); 51 | const ext = extname(path).toLowerCase().replace(/^\./, ""); 52 | for(const grammar of registry.grammars) 53 | if(grammar.fileTypes.some(x => x === ext || x === "." + ext)) 54 | return grammar; 55 | return null; 56 | } 57 | 58 | /** 59 | * Load each JSON and CSON grammar within a directory. 60 | * @param {String} path 61 | * @return {void} 62 | * @internal 63 | */ 64 | function loadGrammarDir(path){ 65 | for(const name of readdirSync(path)) 66 | /\.[jc]son$/i.test(name) && registry.loadGrammarSync(join(path, name)); 67 | } 68 | 69 | /** 70 | * Generate JSON source from an array of tokenised lines. 71 | * @param {Array.} lines 72 | * @return {String} 73 | * @internal 74 | */ 75 | function stringifyTokens(lines){ 76 | let result = ""; 77 | let comma = ""; 78 | for(let line of lines){ 79 | line = line.map(token => [token.value, ...token.scopes]); 80 | result += comma + "[\n" + JSON.stringify(line, null, "\t") 81 | .trim() 82 | .replace(/^\[\s*(.+)\s*\]$/s, "$1") 83 | .replace(/^\t+/gm, "") 84 | .replace(/^\[\n/gm, "[") 85 | .replace(/\n(\],?)$/gm, "$1") 86 | .replace(/",\n/gm, '", ') 87 | .trim() + "\n]"; 88 | comma = ","; 89 | } 90 | result = "[" + result.replace(/,\s*$/, "").trim() + "]"; 91 | JSON.parse(result); // Sanity check 92 | return result; 93 | } 94 | -------------------------------------------------------------------------------- /spec/grammar-spec.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const {join, resolve} = require("path"); 4 | const fs = require("fs"); 5 | 6 | describe("Syntax highlighting", function(){ 7 | this.timeout(30000); 8 | let roff, ditroff, pic; 9 | 10 | before(async () => { 11 | await atom.packages.activatePackage("language-hyperlink"); 12 | const pkg = await atom.packages.activatePackage(resolve(__dirname, "..")); 13 | roff = pkg.grammars.find(g => g.scopeName === "text.roff"); 14 | ditroff = pkg.grammars.find(g => g.scopeName === "source.ditroff"); 15 | pic = pkg.grammars.find(g => g.scopeName === "source.pic"); 16 | }); 17 | 18 | const inputDir = join(__dirname, "fixtures", "input"); 19 | const outputDir = join(__dirname, "fixtures", "output"); 20 | const files = fs.readdirSync(inputDir); 21 | for(const filename of files){ 22 | const input = fs.readFileSync(join(inputDir, filename), "utf8").replace(/\n+$/, ""); 23 | const output = fs.readFileSync(join(outputDir, filename + ".json"), "utf8"); 24 | it(`tokenises ${filename}`, () => { 25 | const grammar = /\.(?:pic|pikchr)$/i.test(filename) ? pic : filename.startsWith("ditroff.") ? ditroff : roff; 26 | const savedTokens = JSON.parse(output).map(l => l.map(([value, ...scopes]) => ({value, scopes}))); 27 | grammar.tokenizeLines(input).should.eql(savedTokens); 28 | }); 29 | } 30 | }); 31 | -------------------------------------------------------------------------------- /styles/styles.less: -------------------------------------------------------------------------------- 1 | @import "syntax-variables"; 2 | 3 | // Fix that sodding highlighting in error notifications 4 | atom-notifications{ 5 | atom-notification.error pre > code{ 6 | background: inherit; 7 | } 8 | 9 | .tty-output{ 10 | background: none; 11 | font-size: var(--editor-font-size); 12 | font-family: var(--editor-font-family); 13 | line-height: var(--editor-line-height); 14 | white-space: pre; 15 | user-select: all; 16 | overflow: auto; 17 | } 18 | } 19 | 20 | // Tab-icons for ManpageViews 21 | .icon-manpage{ 22 | body:not(.file-icons-coloured):not(.file-icons-colourless) &::before{ 23 | font-family: "Octicons Regular"; 24 | font-size: 16px; 25 | top: 1px; 26 | content: "\f007"; 27 | } 28 | 29 | body.file-icons-coloured &::before, 30 | body.file-icons-colourless &::before{ 31 | content: "\e936"; 32 | font-family: file-icons; 33 | font-size: 15px; 34 | top: 3px; 35 | } 36 | 37 | body.file-icons-coloured &::before{ 38 | color: #66783e; 39 | } 40 | } 41 | 42 | .troff-view-pages{ 43 | padding: 1em; 44 | } 45 | .troff-view-page{ 46 | margin-bottom: 1em; 47 | } 48 | 49 | .troff-view{ 50 | background: @syntax-background-color; 51 | color: @syntax-text-color; 52 | 53 | overflow-x: hidden; 54 | overflow-y: auto; 55 | position: absolute; 56 | padding: .5em 1em; 57 | top: 0; 58 | left: 0; 59 | right: 0; 60 | bottom: 0; 61 | } 62 | .troff-view > pre{ 63 | margin: 0; 64 | padding: 0; 65 | background: none; 66 | color: inherit; 67 | } 68 | 69 | // Syntax highlighting refinements 70 | .line > * > .syntax--roff{ 71 | > .syntax--meta.syntax--request.syntax--roff 72 | > .syntax--string.syntax--other.syntax--link{ 73 | color: @syntax-text-color; 74 | } 75 | } 76 | 77 | .theme-seti-syntax{ 78 | .syntax--entity.syntax--name.syntax--link-text.syntax--roff{ 79 | &, & > .syntax--punctuation.syntax--link-text{ 80 | color: #a074c4; 81 | } 82 | } 83 | .syntax--meta.syntax--link-destination.syntax--roff{ 84 | & > .syntax--punctuation.syntax--definition.syntax--string.syntax--begin, 85 | & > .syntax--punctuation.syntax--definition.syntax--string.syntax--end{ 86 | color: #519aba; 87 | } 88 | } 89 | .syntax--ditroff{ 90 | &.syntax--string.syntax--other { color: #7494a3; } 91 | &.syntax--entity.syntax--glyph { color: #a074c4; } 92 | &.syntax--keyword.syntax--function { color: #a074c4; } 93 | } 94 | .syntax--context{ 95 | &.syntax--string.syntax--other { color: #9ac4d7; } 96 | &.syntax--message.syntax--error { color: #cc3e44; } 97 | &.syntax--invalid{ 98 | &.syntax--broken, 99 | &.syntax--unimplemented{ 100 | background: none; 101 | color: #cc3e44; 102 | } 103 | } 104 | &.syntax--sublimelinter.syntax--mark.syntax--warning{ 105 | color: #ffa657; 106 | } 107 | } 108 | .syntax--variable.syntax--other.syntax--user-defined.syntax--pic{ 109 | color: #7494a3; 110 | } 111 | } 112 | 113 | // Hyperlinked man-page references 114 | body:not(.disable-manref-links) .syntax--manref{ 115 | color: @syntax-color-keyword; 116 | cursor: pointer; 117 | font-weight: bold; 118 | &:hover{ 119 | text-decoration: underline; 120 | } 121 | } 122 | 123 | // ASCII control characters 124 | .syntax--punctuation.syntax--ctrl-char.syntax--roff, 125 | .syntax--punctuation.syntax--whitespace.syntax--form-feed.syntax--roff{ 126 | opacity: 0.5; 127 | width: 2ch; 128 | display: inline-block; 129 | position: relative; 130 | color: transparent; 131 | 132 | &::after{ 133 | & when(lightness(@syntax-background-color) < 50%){ color: #4271fb; } 134 | & when(lightness(@syntax-background-color) >= 50%){ color: #00c; } 135 | position: absolute; 136 | left: 0; 137 | width: 100%; 138 | text-align: center; 139 | } 140 | 141 | // Placeholders 142 | &.syntax--start-of-text { &::after{ content: "^B"; }} 143 | &.syntax--end-of-text { &::after{ content: "^C"; }} 144 | &.syntax--end-of-transmission { &::after{ content: "^D"; }} 145 | &.syntax--enquiry { &::after{ content: "^E"; }} 146 | &.syntax--acknowledge { &::after{ content: "^F"; }} 147 | &.syntax--alarm { &::after{ content: "\\a"; }} 148 | &.syntax--form-feed { &::after{ content: "\\f"; }} 149 | &.syntax--delete { &::after{ content: "^?"; }} 150 | } 151 | --------------------------------------------------------------------------------