diff --git a/docs/source/index.rst b/docs/source/index.rst index 8ac56990..03e8cf98 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -57,26 +57,27 @@ already familiar with how to run Python applications on your platform. :maxdepth: 2 :caption: First Steps - introduction - started - interface + int_introduction + int_started + int_interface + int_typography .. toctree:: :maxdepth: 2 :caption: Writing Novels - projects - structure - notes - export + write_projects + write_structure + write_notes + write_export .. toctree:: :maxdepth: 2 :caption: Under the Hood - technical + tech_technical Indices and Tables diff --git a/docs/source/interface.rst b/docs/source/int_interface.rst similarity index 95% rename from docs/source/interface.rst rename to docs/source/int_interface.rst index 48b27691..9191a5d8 100644 --- a/docs/source/interface.rst +++ b/docs/source/int_interface.rst @@ -1,8 +1,8 @@ .. _a_ui: -*************** +************** User Interface -*************** +************** The user interface is kept as simple as possible to avoid distractions when writing. This page lists all the main GUI elements, and explains what they do. @@ -341,11 +341,12 @@ Most features are available as keyboard shortcuts. These are as follows: ":kbd:`Ctrl`:kbd:`B`", "Format selected text, or word under cursor, with strong emphasis (bold)." ":kbd:`Ctrl`:kbd:`C`", "Copy selected text to clipboard." ":kbd:`Ctrl`:kbd:`D`", "Wrap selected text, or word under cursor, in double quotes." - ":kbd:`Ctrl`:kbd:`E`", "If in the project tree, edit a document or folder settings. (Same as :kbd:`F2`)" + ":kbd:`Ctrl`:kbd:`E`", "If in the project tree, edit a document or folder settings. (Same as :kbd:`F2`.)" ":kbd:`Ctrl`:kbd:`F`", "Open the search bar and search for the selected word, if any is selected." - ":kbd:`Ctrl`:kbd:`G`", "Find next occurrence of search word in current document. (Same as :kbd:`F3`)" - ":kbd:`Ctrl`:kbd:`H`", "Open the search and replace bar and search for the selected word, if any is selected. (On Mac, this is :kbd:`Cmd`:kbd:`=`)" + ":kbd:`Ctrl`:kbd:`G`", "Find next occurrence of search word in current document. (Same as :kbd:`F3`.)" + ":kbd:`Ctrl`:kbd:`H`", "Open the search and replace bar and search for the selected word, if any is selected. (On Mac, this is :kbd:`Cmd`:kbd:`=`.)" ":kbd:`Ctrl`:kbd:`I`", "Format selected text, or word under cursor, with emphasis (italic)." + ":kbd:`Ctrl`:kbd:`K`", "Activate the insert commands. The commands are listed in :ref:`a_ui_shortcuts_ins`." ":kbd:`Ctrl`:kbd:`N`", "Create new document." ":kbd:`Ctrl`:kbd:`O`", "Open selected document." ":kbd:`Ctrl`:kbd:`Q`", "Exit novelWriter." @@ -365,7 +366,7 @@ Most features are available as keyboard shortcuts. These are as follows: ":kbd:`Ctrl`:kbd:`Shift`:kbd:`1`", "Replace occurrence of search word in current document, and search for next occurrence." ":kbd:`Ctrl`:kbd:`Shift`:kbd:`A`", "Select all text in current paragraph." ":kbd:`Ctrl`:kbd:`Shift`:kbd:`D`", "Wrap selected text, or word under cursor, in single quotes." - ":kbd:`Ctrl`:kbd:`Shift`:kbd:`G`", "Find previous occurrence of search word in current document. (Same as :kbd:`Shift`:kbd:`F3`)" + ":kbd:`Ctrl`:kbd:`Shift`:kbd:`G`", "Find previous occurrence of search word in current document. (Same as :kbd:`Shift`:kbd:`F3`.)" ":kbd:`Ctrl`:kbd:`Shift`:kbd:`I`", "Import text to the current document from a text file." ":kbd:`Ctrl`:kbd:`Shift`:kbd:`N`", "Create new folder." ":kbd:`Ctrl`:kbd:`Shift`:kbd:`O`", "Open a project." @@ -386,7 +387,7 @@ Most features are available as keyboard shortcuts. These are as follows: ":kbd:`F10`", "Re-build the project outline." ":kbd:`F11`", "Activate full screen mode." ":kbd:`Shift`:kbd:`F1`", "Open the online documentation in the system default browser." - ":kbd:`Shift`:kbd:`F3`", "Find previous occurrence of search word in current document. (Same as :kbd:`Ctrl`:kbd:`Shift`:kbd:`G`)" + ":kbd:`Shift`:kbd:`F3`", "Find previous occurrence of search word in current document. (Same as :kbd:`Ctrl`:kbd:`Shift`:kbd:`G`.)" ":kbd:`Return`", "If in the project tree, open a document for editing." .. note:: @@ -409,11 +410,13 @@ combination for the inserted character or punctuation. ":kbd:`Ctrl`:kbd:`K`, :kbd:`-`", "Insert a short dash (en dash)." ":kbd:`Ctrl`:kbd:`K`, :kbd:`_`", "Insert a long dash (em dash)." - ":kbd:`Ctrl`:kbd:`K`, :kbd:`.`", "Insert ellipsis." - ":kbd:`Ctrl`:kbd:`K`, :kbd:`1`", "Insert left single quote." - ":kbd:`Ctrl`:kbd:`K`, :kbd:`2`", "Insert right single quote." - ":kbd:`Ctrl`:kbd:`K`, :kbd:`3`", "Insert left double quote." - ":kbd:`Ctrl`:kbd:`K`, :kbd:`4`", "Insert right double quote." + ":kbd:`Ctrl`:kbd:`K`, :kbd:`.`", "Insert an ellipsis." + ":kbd:`Ctrl`:kbd:`K`, :kbd:`1`", "Insert a left single quote." + ":kbd:`Ctrl`:kbd:`K`, :kbd:`2`", "Insert a right single quote." + ":kbd:`Ctrl`:kbd:`K`, :kbd:`3`", "Insert a left double quote." + ":kbd:`Ctrl`:kbd:`K`, :kbd:`4`", "Insert a right double quote." + ":kbd:`Ctrl`:kbd:`K`, :kbd:`'`", "Insert a modifier single apostrophe." + ":kbd:`Ctrl`:kbd:`K`, :kbd:`""`", "Insert a modifier double apostrophe." ":kbd:`Ctrl`:kbd:`K`, :kbd:`Return`", "Insert a hard line break." ":kbd:`Ctrl`:kbd:`K`, :kbd:`Space`", "Insert a non-breaking space." ":kbd:`Ctrl`:kbd:`K`, :kbd:`Shift`:kbd:`Space`", "Insert a thin space." diff --git a/docs/source/introduction.rst b/docs/source/int_introduction.rst similarity index 100% rename from docs/source/introduction.rst rename to docs/source/int_introduction.rst diff --git a/docs/source/started.rst b/docs/source/int_started.rst similarity index 100% rename from docs/source/started.rst rename to docs/source/int_started.rst diff --git a/docs/source/int_typography.rst b/docs/source/int_typography.rst new file mode 100644 index 00000000..debddb50 --- /dev/null +++ b/docs/source/int_typography.rst @@ -0,0 +1,93 @@ +.. _a_typ: + +******************* +Typographical Notes +******************* + +novelWriter has some support for typographical symbols that are not usually easily available in many +text editors. This includes for instance the proper unicode quotation marks, dashes, ellipsis, thin +spaces, etc. All these symbols are available from the :guilabel:`Insert` menu, and via keyboard +shortcuts. See :ref:`a_ui_shortcuts_ins`. + +This chapter provides some additional information on how novelWriter handles these symbols. + + +.. _a_typ_notes: + +Special Notes on Symbols +======================== + +Some additional notes on these symbols. + + +Dashes and Ellipsis +------------------- + +With the auto-replace feature enabled (see :ref:`a_ui_edit_auto`), multiple hyphens are converted +automatically to short and long dashes, and three dots to ellipsis. The last auto-replace can always +be reverted with the undo command :kbd:`Ctrl`:kbd:`Z`, reverting the text to what you typed before +the automatic replacement occurred. + + +Single and Double Quotes +------------------------ + +All the different quotation marks listed on the `Quotation Mark`_ Wikipedia page are available, and +can be selected as auto-replaced symbols for straight single and double quote key strokes. The +settings can be found in the :guilabel:`Preferences`. + +Ordinarily, text wrapped in quotes are highlighted by the editor. This is meant as a convenience for +highlighting dialogue between characters. This feature can be disabled in the +:guilabel:`Preferences` if this feature isn't wanted. + +The editor distinguishes between text wrapped in straight quotes and with the user-selected double +quote symbols. This is to help the writer recognise which parts of the text are not using the chosen +quote symbols. Two convenience functions in the :guilabel:`Format` menu can be used to re-format a +selected section of text with the correct quote symbols. + +.. _Quotation Mark: https://en.wikipedia.org/wiki/Quotation_mark + + +Modifier Letter Apostrophes +--------------------------- + +The auto-replace feature will consider any right-facing single straight quote as a quote symbol, +even if it's intended as an apostrophe. This also includes the syntax highlighter, which may decide +to use an apostrophe as the closing symbol of a single quoted string. + +Alternative apostrophes, both single and double, are available. They are special Unicode characters +that are not categorised as punctuation, but modifiers. They are usually renderred the same way as +right single and double quotation marks, but not always, depending on the font. + +There is a Wikipedia article for both the single_ and double_ version of this symbol, explaining +what they're for. + +You can use these symbols if you want, and especially if you have an apostrophe within a single +quoted piece of text. + +.. note:: + On export with the :guilabel:`Build Novel Project` tool, these apostrophes will be replaced + automatically with the corresponding right hand quote symbols. In that respect, it doesn't matter + if you mix them. + +.. _single: https://en.wikipedia.org/wiki/Modifier_letter_apostrophe +.. _double: https://en.wikipedia.org/wiki/Modifier_letter_double_apostrophe + + +Special Space Symbols +--------------------- + +A few variations of the regular space character is supported. The correct typographical way to +separate a number from its unit is with a `thin space`_. It is usually 2/3 the width of a regular +space. For numbers and units, this should in addition be a non-breaking space, that is, the text +wrapping should not add a line break on this particular space. + +A regular space can also be made into a non-breaking space. + +All non-breaking spaces are highlighted with a differently coloured packground. The colour will +depend on the selected colour theme. + +The thin and non-breaking spaces are converted to their corresponding HTML codes on export to HTML +format. For plain text, they are exported as regular spaces. + +.. _thin space: https://en.wikipedia.org/wiki/Thin_space diff --git a/docs/source/technical.rst b/docs/source/tech_technical.rst similarity index 100% rename from docs/source/technical.rst rename to docs/source/tech_technical.rst diff --git a/docs/source/export.rst b/docs/source/write_export.rst similarity index 100% rename from docs/source/export.rst rename to docs/source/write_export.rst diff --git a/docs/source/notes.rst b/docs/source/write_notes.rst similarity index 100% rename from docs/source/notes.rst rename to docs/source/write_notes.rst diff --git a/docs/source/projects.rst b/docs/source/write_projects.rst similarity index 100% rename from docs/source/projects.rst rename to docs/source/write_projects.rst diff --git a/docs/source/structure.rst b/docs/source/write_structure.rst similarity index 100% rename from docs/source/structure.rst rename to docs/source/write_structure.rst diff --git a/nw/constants/constants.py b/nw/constants/constants.py index 7c25fa46..e810dabf 100644 --- a/nw/constants/constants.py +++ b/nw/constants/constants.py @@ -233,6 +233,8 @@ class nwUnicode: U_ENDASH = "\u2013" # Short dash U_EMDASH = "\u2014" # Long dash U_HELLIP = "\u2026" # Ellipsis + U_MAPOSS = "\u02bc" # Modifier letter single apostrophe + U_MAPOSD = "\u02ee" # Modifier letter double apostrophe ## Spaces and Lines U_NBSP = "\u00a0" # Non-breaking space @@ -283,6 +285,8 @@ class nwUnicode: H_ENDASH = "–" H_EMDASH = "—" H_HELLIP = "…" + H_MAPOSS = "ʼ" + H_MAPOSD = "ˮ" ## Spaces H_NBSP = " " diff --git a/nw/constants/enum.py b/nw/constants/enum.py index 49d76f5e..81200a63 100644 --- a/nw/constants/enum.py +++ b/nw/constants/enum.py @@ -112,6 +112,8 @@ class nwDocInsert(Enum): QUOTE_RS = 9 QUOTE_LD = 10 QUOTE_RD = 11 + MODAPOS_S = 12 + MODAPOS_D = 13 # END Enum nwDocInsert diff --git a/nw/core/tohtml.py b/nw/core/tohtml.py index dadf55bd..6053082a 100644 --- a/nw/core/tohtml.py +++ b/nw/core/tohtml.py @@ -54,6 +54,8 @@ class ToHtml(Tokenizer): nwUnicode.U_NBSP : nwUnicode.H_NBSP, nwUnicode.U_THNSP : nwUnicode.H_THNSP, nwUnicode.U_THNBSP : nwUnicode.H_THNBSP, + nwUnicode.U_MAPOSS : nwUnicode.H_RSQUO, + nwUnicode.U_MAPOSD : nwUnicode.H_RDQUO, } self.revDict = {} self.reReplace = [] diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index d10a4d6e..dc25b909 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -612,6 +612,10 @@ class GuiDocEditor(QTextEdit): theText = nwUnicode.U_EMDASH elif theInsert == nwDocInsert.ELLIPSIS: theText = nwUnicode.U_HELLIP + elif theInsert == nwDocInsert.MODAPOS_S: + theText = nwUnicode.U_MAPOSS + elif theInsert == nwDocInsert.MODAPOS_D: + theText = nwUnicode.U_MAPOSD elif theInsert == nwDocInsert.QUOTE_LS: theText = self.typSQOpen elif theInsert == nwDocInsert.QUOTE_RS: diff --git a/nw/gui/mainmenu.py b/nw/gui/mainmenu.py index c462c748..949a8c77 100644 --- a/nw/gui/mainmenu.py +++ b/nw/gui/mainmenu.py @@ -554,6 +554,23 @@ class GuiMainMenu(QMenuBar): # Insert > Separator self.insertMenu.addSeparator() + # Insert > Alt. Single Apostrophe + self.aInsMSApos = QAction("Alt. Single Apostrophe", self) + self.aInsMSApos.setStatusTip("Insert unicode modifier letter single apostrophe") + self.aInsMSApos.setShortcut("Ctrl+K, '") + self.aInsMSApos.triggered.connect(lambda: self._docInsert(nwDocInsert.MODAPOS_S)) + self.insertMenu.addAction(self.aInsMSApos) + + # Insert > Alt. Double Apostrophe + self.aInsMDApos = QAction("Alt. Double Apostrophe", self) + self.aInsMDApos.setStatusTip("Insert unicode modifier letter double apostrophe") + self.aInsMDApos.setShortcut("Ctrl+K, \"") + self.aInsMDApos.triggered.connect(lambda: self._docInsert(nwDocInsert.MODAPOS_D)) + self.insertMenu.addAction(self.aInsMDApos) + + # Insert > Separator + self.insertMenu.addSeparator() + # Insert > Hard Line Break self.aInsHardBreak = QAction("Hard Line Break", self) self.aInsHardBreak.setStatusTip("Insert a hard line break") diff --git a/nw/guimain.py b/nw/guimain.py index 9267a49d..48ea5c73 100644 --- a/nw/guimain.py +++ b/nw/guimain.py @@ -1039,6 +1039,8 @@ class GuiMain(QMainWindow): self.addAction(self.mainMenu.aInsQuoteRS) self.addAction(self.mainMenu.aInsQuoteLD) self.addAction(self.mainMenu.aInsQuoteRD) + self.addAction(self.mainMenu.aInsMSApos) + self.addAction(self.mainMenu.aInsMDApos) self.addAction(self.mainMenu.aInsHardBreak) self.addAction(self.mainMenu.aInsNBSpace) self.addAction(self.mainMenu.aInsThinSpace) diff --git a/tests/test_gui.py b/tests/test_gui.py index f7104308..318c9f1a 100644 --- a/tests/test_gui.py +++ b/tests/test_gui.py @@ -1049,6 +1049,14 @@ def testInsertMenu(qtbot, nwTempGUI, nwFuncTemp, nwTemp): assert nwGUI.docEditor.getText() == nwGUI.mainConf.fmtDoubleQuotes[1] nwGUI.docEditor.clear() + nwGUI.mainMenu.aInsMSApos.activate(QAction.Trigger) + assert nwGUI.docEditor.getText() == nwUnicode.U_MAPOSS + nwGUI.docEditor.clear() + + nwGUI.mainMenu.aInsMDApos.activate(QAction.Trigger) + assert nwGUI.docEditor.getText() == nwUnicode.U_MAPOSD + nwGUI.docEditor.clear() + nwGUI.mainMenu.aInsHardBreak.activate(QAction.Trigger) assert nwGUI.docEditor.getText() == " \n" nwGUI.docEditor.clear()