├── .gitignore
├── .no-sublime-package
├── CHANGES.md
├── LICENSE.md
├── Main.sublime-menu
├── README.md
├── SublimeWritingStyle.py
├── SublimeWritingStyle.sublime-commands
├── SublimeWritingStyle.sublime-settings
├── icons
├── pencil-dark.png
├── pencil-light.png
├── weasel-dark.png
└── weasel-light.png
└── messages.json
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | .idea
3 | README.html
4 | .DS_Store
--------------------------------------------------------------------------------
/.no-sublime-package:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thedataking/SublimeWritingStyle/a8771565bfca721b60db145399399fe9b109e5e6/.no-sublime-package
--------------------------------------------------------------------------------
/CHANGES.md:
--------------------------------------------------------------------------------
1 | Changes in Sublime Writing Style
2 | ================================
3 |
4 | ## 1.0.2
5 |
6 | * Hooks for color theming
7 | * Light and Dark icons
8 |
9 | ## 1.0.1
10 |
11 | * Highlight consecutive duplicate words (e.g., `horse horse`)
12 | * Added `messages.json` and `CHANGES.md`.
13 |
14 | ## 1.0.0
15 |
16 | * Initial release
17 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012-2015 Per Larsen
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "tools",
4 | "caption": "Tools",
5 | "children":
6 | [
7 | {
8 | "id": "packages",
9 | "caption": "Packages",
10 | "children":
11 | [
12 | {
13 | "id": "sublime_writing_style",
14 | "caption": "SublimeWritingStyle",
15 | "children":
16 | [
17 | {
18 | "command": "toggle_sublime_writing_style"
19 | }
20 | ]
21 | }
22 | ]
23 | }
24 | ]
25 | },
26 | {
27 | "caption": "Preferences",
28 | "mnemonic": "n",
29 | "id": "preferences",
30 | "children":
31 | [
32 | {
33 | "caption": "Package Settings",
34 | "mnemonic": "P",
35 | "id": "package-settings",
36 | "children":
37 | [
38 | {
39 | "caption": "SublimeWritingStyle",
40 | "children":
41 | [
42 | {
43 | "command": "open_file",
44 | "args": {"file": "${packages}/Writing Style/SublimeWritingStyle.sublime-settings"},
45 | "caption": "Settings – Default"
46 | },
47 | {
48 | "command": "open_file",
49 | "args": {"file": "${packages}/User/SublimeWritingStyle.sublime-settings"},
50 | "caption": "Settings – User"
51 | }
52 | ]
53 | }
54 | ]
55 | }
56 | ]
57 | }
58 | ]
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | SublimeWritingStyle
2 | ===================
3 |
4 | Improve your writing style with this Sublime Text package.
5 | It supports both Sublime Text 2 and 3.
6 |
7 | Why Should I Write in Style?
8 | ------------------------------
9 |
10 | Practicing your writing skills will make you a more effective communicator.
11 |
12 | How Does This Package Help Me?
13 | -----------------------------------
14 |
15 | It does two things. First, it helps you use *active voice* instead of *passive voice*.
16 | Consider these two sentences:
17 |
18 | - The car was driven by the boy.
19 |
20 | - The boy drove the car.
21 |
22 | Which one is simpler? (Hint, it's the second, active one.) Using active voice simultaneously makes your text shorter and more engaging to the reader. Unfortunately, it takes some practice to spot passive sentences.
23 | Passive voice indicators are forms of *to be* (am, is, are, was, were, be, been, being) plus another verb (often ending in *ed*).
24 |
25 | Second, this package highlights *weasel words*. Use these judgmental words sparingly. A few examples: *very, clearly, and, relatively*.
26 |
27 | Both the list of passive voice indicators and weasel words are customizable using Sublime Text settings files. Use the `extra_words` settings key to define additional highlighted words.
28 |
29 | How to Install
30 | ------------------------------------------
31 |
32 | #### Using [Package Control][0] (Recommended):
33 |
34 | 1. [Install][1] Package Control
35 | 2. Open the command palette (`cmd+shift+P`) then `Package Control: Install Package`
36 | 3. Search for `Writing Style`
37 | 4. (Optionally) Reopen any windows
38 |
39 | #### Manually:
40 |
41 | 1. Open the `Preferences > Browse Packages…` menu
42 | 2. Extract the [zip archive][zip] to the `Packages` directory, rename it to `Writing Style`, and delete the zip archive
43 | 3. Restart Sublime Text
44 |
45 | How Can I Configure What gets Highlighted?
46 | ------------------------------------------
47 | Create (or open) a file called ```SublimeWritingStyle.sublime-settings``` in your Packages/User directory.
48 | For instance, you can add extra weasel words using the ```extra_words``` key or overwrite existing weasel words using the ```weasel_words``` key.
49 | You can enable the plugin on additional file types using the ```extra_extensions``` key.
50 |
51 | How Can I Adjust the Colors of the Highlights?
52 | -----------------------------------------------
53 | The icons come in dark and light versions. You can switch this by adding this to your user settings:
54 |
55 | ```json
56 | "theme": "light"
57 | ```
58 |
59 | Valid theme values are: `light`, `dark`, and `none`. The last option turns off gutter icons.
60 |
61 |
62 | Add this to your theme, and adjust the colors as necessary:
63 |
64 | ```xml
65 |
66 |
67 | name
68 | SublimeWritingStyle.Passive
69 | scope
70 | writingstyle.passive
71 | settings
72 |
73 | foreground
74 | #40BFFF
75 |
76 |
77 |
78 | name
79 | SublimeWritingStyle.Weasel
80 | scope
81 | writingstyle.weasel
82 | settings
83 |
84 | foreground
85 | #E09500
86 |
87 |
88 | ```
89 |
90 |
91 | Who Inspired This Package?
92 | --------------------------
93 |
94 | [Stefan Brunthaler](http://www.ics.uci.edu/~sbruntha/) extended the [writegood-mode](https://github.com/bnbeckwith/writegood-mode) for [Emacs](http://www.gnu.org/software/emacs/) in a similar fashion.
95 |
96 | Icons made by [Freepik][2] from [www.flaticon.com][3] is licensed by [Creative Commons BY 3.0][4]
97 |
98 | [0]: https://sublime.wbond.net/
99 | [1]: https://sublime.wbond.net/installation
100 | [2]: http://www.freepik.com
101 | [3]: http://www.flaticon.com
102 | [4]: http://creativecommons.org/licenses/by/3.0/
103 | [zip]: https://github.com/thedataking/SublimeWritingStyle/archive/master.zip
104 |
--------------------------------------------------------------------------------
/SublimeWritingStyle.py:
--------------------------------------------------------------------------------
1 | import os.path
2 | import sublime
3 | import sublime_plugin
4 |
5 | # Sublime Text 2 API reference:
6 | # http://www.sublimetext.com/docs/2/api_reference.html
7 |
8 | # Acknowledgements:
9 | # Several snippets inspired by WordHighlight plugin for
10 | # Sublime Text (https://github.com/SublimeText/WordHighlight)
11 |
12 | # TODO: detect long and complex sentences
13 | # TODO: detect adverbs
14 | # TODO: detect patterns that can be simplified
15 |
16 | weasel_word_regions = []
17 | passive_voice_regions = []
18 |
19 | def mark_words(view, search_all=True):
20 | global settings, weasel_word_regions, passive_voice_regions
21 |
22 | def find_words(pattern):
23 | if search_all:
24 | if settings.debug:
25 | print('sublimewritingstyle: searching whole document')
26 | found_regions = view.find_all(pattern, sublime.IGNORECASE, '', [])
27 | else:
28 | if settings.debug:
29 | print('sublimewritingstyle: searching around visible region')
30 | found_regions = []
31 | chunk_size = 2 * 10 ** 3
32 |
33 | visible_region = view.visible_region()
34 | begin = max(visible_region.begin() - chunk_size, 0)
35 | end = min(visible_region.end() + chunk_size, view.size())
36 | from_point = begin
37 | while True:
38 | region = view.find(pattern, from_point, sublime.IGNORECASE)
39 | if region:
40 | found_regions.append(region)
41 | rend = region.end()
42 | if rend > end:
43 | break
44 | else:
45 | from_point = rend
46 | else:
47 | break
48 | return found_regions
49 | # end of find_words
50 |
51 | def lazy_mark_regions(new_regions, old_regions, style_key, color_scope_name, symbol_name, draw_style):
52 | if old_regions != new_regions or True:
53 | # print 'adding new regions'
54 | view.erase_regions(style_key)
55 | # name, regions, style, symbol in gutter, draw outlined
56 | if settings.theme == 'none':
57 | view.add_regions(style_key, new_regions, color_scope_name, flags = draw_style)
58 | else:
59 | view.add_regions(style_key, new_regions, color_scope_name, symbol_name, draw_style)
60 | return new_regions
61 | # end of lazy_mark_regions
62 |
63 | # passive words
64 | new_regions = find_words(settings.passive_voice_pattern)
65 | passive_voice_regions = lazy_mark_regions(
66 | new_regions,
67 | passive_voice_regions,
68 | 'SublimeWritingStyle.Passive',
69 | 'writingstyle.passive',
70 | os.path.join('Packages', 'Writing Style', 'icons', 'pencil-dark.png' if settings.theme == 'dark' else 'pencil-light.png'),
71 | sublime.DRAW_NO_FILL + sublime.DRAW_NO_OUTLINE + sublime.DRAW_STIPPLED_UNDERLINE)
72 |
73 | # weasel words
74 | new_regions = find_words(settings.pattern)
75 | weasel_word_regions = lazy_mark_regions(
76 | new_regions,
77 | weasel_word_regions,
78 | 'SublimeWritingStyle.Weasel',
79 | 'writingstyle.weasel',
80 | os.path.join('Packages', 'Writing Style', 'icons', 'weasel-dark.png' if settings.theme == 'dark' else 'weasel-light.png'),
81 | sublime.DRAW_NO_FILL + sublime.DRAW_NO_OUTLINE + sublime.DRAW_SQUIGGLY_UNDERLINE)
82 |
83 |
84 | class SublimeWritingStyleListener(sublime_plugin.EventListener):
85 | enabled = False
86 |
87 | @classmethod
88 | def disable(cls):
89 | """
90 | marks package as disabled and removes marked words.
91 | """
92 | cls.enabled = False
93 | window = sublime.active_window()
94 | if window:
95 | view = window.active_view()
96 | if view:
97 | view.erase_regions("SublimeWritingStyle.Passive")
98 | view.erase_regions("SublimeWritingStyle.Weasel")
99 |
100 | def handle_event(self, view):
101 | """
102 | determines if the package status changed. marks words when turned on.
103 | """
104 | global settings
105 |
106 | # does settings enable package?
107 | if not settings.enabled:
108 | # ... no!
109 | SublimeWritingStyleListener.disable()
110 | return
111 |
112 | # check this file if either it's enabled or if the extensions list is empty
113 | file_name = view.file_name()
114 |
115 | ext = ''
116 | if file_name:
117 | # Use the extension if it exists, otherwise use the whole filename
118 | ext = os.path.splitext(file_name)
119 | if ext[1]:
120 | ext = ext[1]
121 | else:
122 | ext = os.path.split(file_name)[1]
123 |
124 | allowed_extensions = settings.get('extensions')
125 | if (not allowed_extensions) or ext in allowed_extensions:
126 | if not SublimeWritingStyleListener.enabled:
127 | SublimeWritingStyleListener.enabled = True
128 |
129 | mark_words(view)
130 | return
131 |
132 | SublimeWritingStyleListener.disable() # turn off for this file!
133 |
134 | def on_activated(self, view):
135 | if not view.is_loading():
136 | self.handle_event(view)
137 |
138 | def on_post_save(self, view):
139 | self.handle_event(view)
140 |
141 | def on_load(self, view):
142 | self.handle_event(view)
143 |
144 | def on_modified(self, view):
145 | if SublimeWritingStyleListener.enabled:
146 | mark_words(view, search_all=False)
147 |
148 |
149 | def load_settings():
150 | """
151 | runs when package loads.
152 | """
153 | settings = sublime.load_settings('SublimeWritingStyle.sublime-settings')
154 |
155 | def process_settings(settings):
156 | """
157 | add properties reflecting the loaded settings.
158 | """
159 | def build_passive_voice_regex(linking_verbs, irregulars):
160 | return r'(?\\)+\\([[:word:]]+ed\\|"
37 | "passive_voice_linking_verbs": ["am", "are", "were", "being", "is", "been", "was", "be"],
38 | "extensions": [".py", ".tex", ".md", ".mdown", ".markdown", ".txt", ".rst"],
39 | "enabled": true,
40 | "theme": "light"
41 | }
42 |
--------------------------------------------------------------------------------
/icons/pencil-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thedataking/SublimeWritingStyle/a8771565bfca721b60db145399399fe9b109e5e6/icons/pencil-dark.png
--------------------------------------------------------------------------------
/icons/pencil-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thedataking/SublimeWritingStyle/a8771565bfca721b60db145399399fe9b109e5e6/icons/pencil-light.png
--------------------------------------------------------------------------------
/icons/weasel-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thedataking/SublimeWritingStyle/a8771565bfca721b60db145399399fe9b109e5e6/icons/weasel-dark.png
--------------------------------------------------------------------------------
/icons/weasel-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thedataking/SublimeWritingStyle/a8771565bfca721b60db145399399fe9b109e5e6/icons/weasel-light.png
--------------------------------------------------------------------------------
/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "install": "README.md",
3 | "1.0.1": "CHANGES.md",
4 | "1.0.2": "CHANGES.md"
5 | }
--------------------------------------------------------------------------------