Include HTML docs in minimal installs (#856)

* Link to stable docs for stable release, otherwise latest docs
* Add build command to setup for making HTML docs
* Change the documentation menu entry to open either online or local HTML
* Update docs build instructions in docs
This commit is contained in:
Veronica Berglyd Olsen
2021-08-18 00:13:28 +02:00
committed by GitHub
parent a9368904e5
commit eee0f5e4c9
7 changed files with 111 additions and 102 deletions
+1
View File
@@ -17,6 +17,7 @@ i18n/*.qph
# Documentation
/docs/build/
/nw/assets/help/html/
*.qch
*.qhc
+7 -14
View File
@@ -141,13 +141,12 @@ generated. It requires the following Python packages on Debian and Ubuntu.
* ``python3-sphinx``
* ``python3-sphinx-rtd-theme``
* ``python3-sphinxcontrib.qthelp``
Or from PyPi:
.. code-block:: console
pip install sphinx sphinx-rtd-theme sphinxcontrib-qthelp
pip install sphinx sphinx-rtd-theme
The documentation can then be built from the ``docs`` folder in the source code by running:
@@ -158,19 +157,13 @@ The documentation can then be built from the ``docs`` folder in the source code
If successful, the documentation should be available in the ``docs/build/html`` folder and you can
open the ``index.html`` file in your browser.
The documentation can also be built for the Qt Assistant. To build the help packages from the
documentation source, run the following from the root source folder:
You can also build the documentation by using the setup script:
.. code-block:: console
python setup.py qthelp
python setup.py docs
The setup script will copy the generated files into the ``nw/assets/help`` folder, and novelWriter
will detect the presence of the files and redirect the menu help entry to open help locally instead
of sending the user to the website. Pressing the :kbd:`F1` key will in any case try to open help
locally first, then send you to the website as a fallback.
.. note::
In order for the local version of help to work, the Qt Assistant must be installed on the local
computer. If it isn't available, or novelWriter cannot find it, the help feature will fall back
to redirecting you to the documentation website.
This does the same as the ``make help`` command, but in addition it copies the documentation into
novelWriter's assets folder. This will make it possible to open the documentation from inside of
novelWriter by pressing :kbd:`F1` even without an internet connection, as it will instead open the
local copy.
+1 -17
View File
@@ -26,7 +26,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
import os
import sys
import json
import shutil
import logging
from time import time
@@ -72,11 +71,9 @@ class Config:
self.themeRoot = None # The full path to the nw/assets/themes folder
self.dictPath = None # The full path to the nw/assets/dict folder
self.iconPath = None # The full path to the nw/assets/icons folder
self.helpPath = None # The full path to the novelwriter .qhc help file
# Runtime Settings and Variables
self.confChanged = False # True whenever the config has chenged, false after save
self.hasHelp = False # True if the Qt help files are present in the assets folder
# General
self.guiTheme = "default"
@@ -230,8 +227,7 @@ class Config:
self.kernelVer = "Unknown"
# Packages
self.hasEnchant = False # The pyenchant package
self.hasAssistant = False # The Qt Assistant executable
self.hasEnchant = False # The pyenchant package
# Recent Cache
self.recentProj = {}
@@ -360,11 +356,6 @@ class Config:
if self.spellLanguage is None:
self.spellLanguage = "en"
# Check if local help files exist
self.helpPath = os.path.join(self.assetPath, "help", "novelWriter.qhc")
self.hasHelp = os.path.isfile(self.helpPath)
self.hasHelp &= os.path.isfile(os.path.join(self.assetPath, "help", "novelWriter.qch"))
logger.debug("Config initialisation complete")
return True
@@ -930,13 +921,6 @@ class Config:
self.hasEnchant = False
logger.debug("Checking package 'pyenchant': Missing")
assistPath = shutil.which("assistant")
self.hasAssistant = assistPath is not None
if self.hasAssistant:
logger.debug("Checking executable 'assistant': OK")
else:
logger.debug("Checking executable 'assistant': Missing")
return
# END Class Config
+38 -57
View File
@@ -23,10 +23,15 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import os
import nw
import logging
from PyQt5.QtCore import QUrl, QProcess
from http.client import HTTPSConnection
from urllib.parse import urljoin
from urllib.request import pathname2url
from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QDesktopServices
from PyQt5.QtWidgets import QMenuBar, QAction
@@ -46,9 +51,6 @@ class GuiMainMenu(QMenuBar):
self.theParent = theParent
self.theProject = theParent.theProject
# Internals
self._assistProc = None
# Build Menu
self._buildProjectMenu()
self._buildDocumentMenu()
@@ -89,25 +91,6 @@ class GuiMainMenu(QMenuBar):
)
return
def closeHelp(self):
"""Close the process used for the Qt Assistant, if it is open.
"""
if self._assistProc is None:
return
if self._assistProc.state() == QProcess.Starting:
if self._assistProc.waitForStarted(10000):
self._assistProc.terminate()
else:
self._assistProc.kill()
elif self._assistProc.state() == QProcess.Running:
self._assistProc.terminate()
if not self._assistProc.waitForFinished(10000):
self._assistProc.kill()
return
##
# Update Menu on Settings Changed
##
@@ -148,28 +131,38 @@ class GuiMainMenu(QMenuBar):
self.theProject.setAutoOutline(theMode)
return True
def _openAssistant(self, isChecked=False):
"""Open the documentation in Qt Assistant.
"""
if not self.mainConf.hasHelp:
self._openWebsite(nw.__docurl__)
return False
self._assistProc = QProcess(self)
self._assistProc.start("assistant", ["-collectionFile", self.mainConf.helpPath])
if not self._assistProc.waitForStarted(10000):
self._openWebsite(nw.__docurl__)
return False
return True
def _openWebsite(self, theUrl):
"""Open a URL in the system's default browser.
"""
QDesktopServices.openUrl(QUrl(theUrl))
return True
def _openDocumentation(self):
"""Open the documentation, and select whether it should be the
stable or latest version. If no internet connection, open
local.
"""
if nw.__hexversion__[-2] == "f":
docsPath = "/en/stable/"
else:
docsPath = "/en/latest/"
try:
conn = HTTPSConnection(nw.__docurl__.replace("https://", ""))
conn.request("HEAD", docsPath)
resp = conn.getresponse()
hasAccess = resp.code == 200
except Exception:
hasAccess = False
docsFile = os.path.join(self.mainConf.assetPath, "help", "html", "index.html")
if hasAccess or not os.path.isfile(docsFile):
self._openWebsite(nw.__docurl__ + docsPath)
else:
self._openWebsite(urljoin("file:", pathname2url(docsFile)))
return
##
# Menu Builders
##
@@ -1113,24 +1106,12 @@ class GuiMainMenu(QMenuBar):
# Help > Separator
self.helpMenu.addSeparator()
# Document > Documentation
if self.mainConf.hasHelp and self.mainConf.hasAssistant:
self.aHelpLoc = QAction(self.tr("Documentation (Local)"), self)
self.aHelpLoc.setStatusTip(self.tr("View local documentation with Qt Assistant"))
self.aHelpLoc.triggered.connect(self._openAssistant)
self.aHelpLoc.setShortcut("F1")
self.helpMenu.addAction(self.aHelpLoc)
self.aHelpWeb = QAction(self.tr("Documentation (Online)"), self)
self.aHelpWeb.setStatusTip(
self.tr("View online documentation at {0}").format(nw.__docurl__)
)
self.aHelpWeb.triggered.connect(lambda: self._openWebsite(nw.__docurl__))
if self.mainConf.hasHelp and self.mainConf.hasAssistant:
self.aHelpWeb.setShortcut("Shift+F1")
else:
self.aHelpWeb.setShortcuts(["F1", "Shift+F1"])
self.helpMenu.addAction(self.aHelpWeb)
# Help > Documentation
self.aHelpDocs = QAction(self.tr("Documentation"), self)
self.aHelpDocs.setStatusTip(self.tr("Open documentation in browser"))
self.aHelpDocs.triggered.connect(self._openDocumentation)
self.aHelpDocs.setShortcut("F1")
self.helpMenu.addAction(self.aHelpDocs)
# Help > Separator
self.helpMenu.addSeparator()
+1 -4
View File
@@ -1190,7 +1190,6 @@ class GuiMain(QMainWindow):
self.mainConf.saveConfig()
self.reportConfErr()
self.mainMenu.closeHelp()
qApp.quit()
@@ -1373,9 +1372,7 @@ class GuiMain(QMainWindow):
self.addAction(self.mainMenu.aPreferences)
# Help
if self.mainConf.hasHelp and self.mainConf.hasAssistant:
self.addAction(self.mainMenu.aHelpLoc)
self.addAction(self.mainMenu.aHelpWeb)
self.addAction(self.mainMenu.aHelpDocs)
return True
+63
View File
@@ -221,6 +221,56 @@ def buildQtDocs():
return
##
# Html Documentation Builder (docs)
##
def buildHtmlDocs():
"""This function will build the Sphinx HTML documentation. The files
are then copied into the nw/assets/help/html directory and can be
included in builds.
"""
buildDir = os.path.join("docs", "build", "html")
helpDir = os.path.join("nw", "assets", "help", "html")
print("")
print("Building Documentation")
print("======================")
print("")
buildFail = False
try:
subprocess.call(["make", "-C", "docs", "clean"])
subprocess.call(["make", "-C", "docs", "html"])
except Exception as e:
print("Docs Build Error:")
print(str(e))
buildFail = True
try:
if os.path.isdir(helpDir):
shutil.rmtree(helpDir)
shutil.copytree(buildDir, helpDir)
except Exception as e:
print("Docs Build Error:")
print(str(e))
buildFail = True
print("")
if buildFail:
print("Documentation build: FAILED")
print("")
print("Dependencies:")
print(" * pip install sphinx")
print(" * pip install sphinx-rtd-theme")
sys.exit(1)
else:
print("Documentation build: OK")
print("")
return
##
# Qt Linguist QM Builder (qtlrelease)
##
@@ -349,6 +399,14 @@ def makeMinimalPackage(targetOS):
print(str(e))
sys.exit(1)
# Build docs
try:
buildHtmlDocs()
except Exception as e:
print("Failed with error:")
print(str(e))
sys.exit(1)
# Make translation files
try:
buildQtI18n()
@@ -1137,6 +1195,7 @@ if __name__ == "__main__":
"",
"Additional Builds:",
"",
" docs Build the help documentation as HTML."
" qthelp Build the help documentation for use with the Qt Assistant.",
" qtlupdate Update the translation files for internationalisation.",
" qtlrelease Build the language files for internationalisation.",
@@ -1203,6 +1262,10 @@ if __name__ == "__main__":
# Additional Builds
# =================
if "docs" in sys.argv:
sys.argv.remove("docs")
buildHtmlDocs()
if "qthelp" in sys.argv:
sys.argv.remove("qthelp")
buildQtDocs()
-10
View File
@@ -544,14 +544,4 @@ def testBaseConfig_Internal(monkeypatch, tmpConf):
tmpConf._checkOptionalPackages()
assert tmpConf.hasEnchant is False
with monkeypatch.context() as mp:
mp.setattr("shutil.which", lambda *a: "stuff")
tmpConf._checkOptionalPackages()
assert tmpConf.hasAssistant is True
with monkeypatch.context() as mp:
mp.setattr("shutil.which", lambda *a: None)
tmpConf._checkOptionalPackages()
assert tmpConf.hasAssistant is False
# END Test testBaseConfig_Internal