- Timestamp:
- Mar 20, 2023 12:01:53 PM (23 months ago)
- Location:
- trunk/doc/manual
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/doc/manual/Makefile.kmk
r99060 r99064 581 581 ################################################################################################################################# 582 582 583 584 ##########################################################################################585 #586 # DITA stuff common to pdf, qhelp, and html outputs.587 # - copy DITA-OT library (binaries etc) since at each run several run-time config588 # files are updated.589 # - create dita/topic folder and copy all user manual dita files under that.590 # - copy all images under dita/topics/images and UserManual.ditamap under dita folder591 # - copy all man_V*.xml docbook files under dita/topic folder.592 # - flatten refsect1/refsect2 hierarchy in man_V*.xml docbook files by593 # using refsect2_to_refsect1.py.594 # - convert man_V*.xml files into dita files595 # - mark external link in the man_V*.dita files596 # - correct all reference targets by calling correct_references.py.597 #598 # Note! INSTALL_STAGING is likely to hardlink the files, thus we must use +| below599 # when copying files as much won't change timestamp. It would in fact be a _lot_600 # better to copy the files individually.601 #602 ##########################################################################################603 604 583 # 605 584 # 1. We copy/hardlink all the files under <lang>/dita/* to the corresponding … … 761 740 762 741 763 764 ########################################################################################## 765 # 766 # UserManual.html 767 # 768 ########################################################################################## 769 770 $(VBOX_PATH_MANUAL_OUTBASE)/en_US/UserManual.zip: \ 771 $(VBOX_PATH_MANUAL_OUTBASE)/en_US/html-chunks/index.html 772 $(call MSG_L1,Packing documentation $@) 773 $(QUIET)$(RM) -f $@ 774 $(QUIET)$(REDIRECT) -C $(VBOX_PATH_MANUAL_OUTBASE)/en_US/ -- $(VBOX_ZIP) \ 775 -9 -r $@ html-chunks 776 777 $(VBOX_PATH_MANUAL_OUTBASE)/en_US/html-chunks/index.html: \ 778 $(VBOX_USER_MANUAL_DITA_STAGED_FILES_en_US) \ 779 $(VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES_en_US) 780 $(call MSG_L1,Building html chunks $@) 781 $(QUIET)$(RM) -Rf -- "$(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita-ot-html-chunks/" 782 $(QUIET)$(call VBOX_DITA_RUN_DOST,$(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita-ot-html-chunks) \ 783 "/i:$(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita/UserManual.ditamap" \ 784 "/transtype:xhtml" \ 785 "/outdir:$(@D)" \ 786 "/tempdir:$(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita/temp_xhtml" "/debug" 787 788 # disable for now 789 ## bird: Remove @chunk attrib from Glossary.dita topicref and add chunk="to-content" to bootmap for single html experiments. 790 ## See https://docs.oasis-open.org/dita/v1.2/os/spec/archSpec/chunking.html 791 ## and https://www.oxygenxml.com/forum/post25114.html?hilit=dita%20xhtml%20chunk#p25114 792 ## for further clues. 793 #html:: $(VBOX_PATH_MANUAL_OUTBASE)/en_US/html-single/UserManual.html 794 795 html:: $(VBOX_PATH_MANUAL_OUTBASE)/en_US/html-chunks/index.html 796 qhelp:: $(addprefix $(VBOX_PATH_MANUAL_OUTBASE)/en_US/qhelp/, $(VBOX_QHELP_OUTPUT_FILES)) 797 html-zip:: $(VBOX_PATH_MANUAL_OUTBASE)/en_US/UserManual.zip 798 799 # 800 # A few things which are shared between htmlhelp and qhelp docs. 801 # TODO: This is Docbook related work. Left here in case we can reuse some of 802 # the ideas from it for DITA-OT. 803 # 804 805 VBOX_DOCBOOK_HTMLHELP_FORMATCFG = \ 806 $(VBOX_PATH_MANUAL_SRC)/docbook-htmlhelp-formatcfg.xsl \ 807 $(VBOX_PATH_MANUAL_SRC)/common-formatcfg.xsl \ 808 $(VBOX_PATH_MANUAL_SRC)/common-html-formatcfg.xsl 809 810 # Prepare the XSL file for our title page, htmlhelp and qhelp variant. 811 $(VBOX_PATH_MANUAL_OUTBASE)/titlepage-htmlhelp.xsl: \ 812 $(VBOX_PATH_MANUAL_SRC)/titlepage-htmlhelp.xml $(MAKEFILE_CURRENT) | $$(dir $$@) 813 $(call MSG_L1,xsltproc $<) 814 $(QUIET)$(RM) -f [email protected] $@ 815 $(QUIET)$(VBOX_XSLTPROC) --xinclude --nonet -o [email protected] $(VBOX_PATH_DOCBOOK)/template/titlepage.xsl $< 816 $(QUIET)$(MV) -f [email protected] $@ 817 818 819 ########################################################################################## 820 # 821 # Use DITA-OT to create pdf/hhp out of UserManual.ditamap. See usermanual.pdf under 822 # DITA-OT-xxxxx/doc folder for details. 823 # 824 ########################################################################################## 825 826 827 # Note! The /tempdir is deleted, recreated, used and deleted again for each run. So, be careful where you point it. 742 # 743 # 3a. UserManual.pdf - Run dost.jar from DITA-OT to produce the PDF version. 744 # 745 # Note! The /tempdir is deleted, recreated, used and deleted again for each 746 # run. So, be careful where you point it. 828 747 # Note! This crappy utility may fail to find files (or fail to parse the 829 748 # command line) and still return a successfully (0) exit code. 749 # 830 750 define def_ditamap_to_pdf 831 751 $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/UserManual.pdf \ … … 852 772 usermanual UserManual.pdf:: $(PATH_STAGE_BIN)/UserManual.pdf 853 773 774 775 # 776 # 3b. UserManual.html - Run dost.jar from DITA-OT to produce the HTML versions. 777 # 778 # We produce both chunked and singled paged HTML versions of the en_US manual 779 # mainly for uploading to virtualbox.org. The docs build box produces a zip 780 # including these. 781 # 782 783 $(VBOX_PATH_MANUAL_OUTBASE)/en_US/html-chunks/index.html: \ 784 $(VBOX_USER_MANUAL_DITA_STAGED_FILES_en_US) \ 785 $(VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES_en_US) 786 $(call MSG_L1,Building html chunks $@) 787 $(QUIET)$(RM) -Rf -- "$(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita-ot-html-chunks/" 788 $(QUIET)$(call VBOX_DITA_RUN_DOST,$(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita-ot-html-chunks) \ 789 "/i:$(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita/UserManual.ditamap" \ 790 "/transtype:xhtml" \ 791 "/outdir:$(@D)" \ 792 "/tempdir:$(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita/temp_xhtml" # "/debug" 793 794 # disable for now 795 ## bird: Remove @chunk attrib from Glossary.dita topicref and add chunk="to-content" to bootmap for single html experiments. 796 ## See https://docs.oasis-open.org/dita/v1.2/os/spec/archSpec/chunking.html 797 ## and https://www.oxygenxml.com/forum/post25114.html?hilit=dita%20xhtml%20chunk#p25114 798 ## for further clues. 799 #html:: $(VBOX_PATH_MANUAL_OUTBASE)/en_US/html-single/UserManual.html 800 801 $(VBOX_PATH_MANUAL_OUTBASE)/en_US/UserManual.zip: \ 802 $(VBOX_PATH_MANUAL_OUTBASE)/en_US/html-chunks/index.html 803 $(call MSG_L1,Packing documentation $@) 804 $(QUIET)$(RM) -f $@ 805 $(QUIET)$(REDIRECT) -C $(VBOX_PATH_MANUAL_OUTBASE)/en_US/ -- $(VBOX_ZIP) \ 806 -9 -r $@ html-chunks 807 808 html:: $(VBOX_PATH_MANUAL_OUTBASE)/en_US/html-chunks/index.html 809 html-zip:: $(VBOX_PATH_MANUAL_OUTBASE)/en_US/UserManual.zip 810 811 812 # 813 # A few things which are shared between htmlhelp and qhelp docs. 814 # TODO: This is Docbook related work. Left here in case we can reuse some of 815 # the ideas from it for DITA-OT. 816 # 817 818 VBOX_DOCBOOK_HTMLHELP_FORMATCFG = \ 819 $(VBOX_PATH_MANUAL_SRC)/docbook-htmlhelp-formatcfg.xsl \ 820 $(VBOX_PATH_MANUAL_SRC)/common-formatcfg.xsl \ 821 $(VBOX_PATH_MANUAL_SRC)/common-html-formatcfg.xsl 822 823 # Prepare the XSL file for our title page, htmlhelp and qhelp variant. 824 $(VBOX_PATH_MANUAL_OUTBASE)/titlepage-htmlhelp.xsl: \ 825 $(VBOX_PATH_MANUAL_SRC)/titlepage-htmlhelp.xml $(MAKEFILE_CURRENT) | $$(dir $$@) 826 $(call MSG_L1,xsltproc $<) 827 $(QUIET)$(RM) -f [email protected] $@ 828 $(QUIET)$(VBOX_XSLTPROC) --xinclude --nonet -o [email protected] $(VBOX_PATH_DOCBOOK)/template/titlepage.xsl $< 829 $(QUIET)$(MV) -f [email protected] $@ 830 831 # end old stuff. 832 833 if defined(VBOX_WITH_DOCS_QHELP) && !defined(VBOX_ONLY_SDK) 834 # 835 # 3c. VirtualBox.qch + VirtualBox.qhc - Qt compressed help and collection file. 836 # 837 # See usermanual.pdf under DITA-OT-xxxxx/doc folder for details. 838 # 839 840 # Enable Qt and locate the Qt help generator. 841 ifdef VBOX_WITH_QT6 842 USES += qt6 843 VBOX_QHELPGENERATOR = $(PATH_TOOL_QT6_LIBEXEC)/qhelpgenerator 844 else 845 USES += qt5 846 VBOX_QHELPGENERATOR_VERSION_MINOR = $(shell $(REDIRECT) -E QT_QPA_PLATFORM_PLUGIN_PATH=$(PATH_SDK_QT5)/plugins -- $(PATH_TOOL_QT5_BIN)/qhelpgenerator -v 2>/dev/null | $(SED) -ne 's/.*(Qt [1-9][0-9]*\.\([1-9][0-9]*\)\.[1-9][0-9]*).*$$/\1/p') 847 VBOX_QHELPGENERATOR = $(PATH_TOOL_QT5_BIN)/$(if-expr $(VBOX_QHELPGENERATOR_VERSION_MINOR) >= 12,qhelpgenerator,qcollectiongenerator) 848 endif 849 850 ## Build QHelp version of manual for given language. 851 # @param 1 Language 852 # @param 2 The language specific qhelp output directory. 853 define def_vbox_usermanual_as_qhelp 854 855 # 1. Generate UserManual.hpp using DITA-OT. 856 # 857 # Setting HHCDIR here so that it fails to locate hcc.exe and always skips the 858 # compilation step that produces the .chm-file, since we don't need it and it 859 # mangles the path so it always fails anyway. 860 $(2)/UserManual.hhp: \ 861 $(VBOX_USER_MANUAL_DITA_STAGED_FILES_$(1)) \ 862 $(VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES_$(1)) 863 $$(QUIET)$(RM) -Rf -- "$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita-ot-qhelp/" 864 $$(QUIET)$$(call VBOX_DITA_RUN_DOST,$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita-ot-qhelp, -EHHCDIR="$$(@D)") \ 865 "/i:$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/UserManual.ditamap" \ 866 "/transtype:htmlhelp" \ 867 "/outdir:$(2)" \ 868 "/tempdir:$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/temp_qhelp" 869 870 ditamap-to-htmlhelp: $(2)/UserManual.hhp 871 872 # 2. Generate a Qt Help Project file (QHP) using htmlhelp-qthelp.py. 873 $(2)/UserManual.qhp: \ 874 $(2)/UserManual.hhp \ 875 $$(VBOX_PATH_MANUAL_SRC)/htmlhelp-qthelp.py \ 876 | $$$$(dir $$$$@) 877 $$(call MSG_L1,htmlhelp-qthelp.py $$<,=> $$@) 878 $$(QUIET)$$(RM) -f -- "$$@" 879 $$(QUIET)$$(VBOX_BLD_PYTHON) $$(VBOX_PATH_MANUAL_SRC)/htmlhelp-qthelp.py \ 880 -d "$$(<D)" -o "$$@" -f UserManual.hhp -t UserManual.hhc 881 882 # 3. Copy the Qt help configuration file from source to the output dir. 883 $(2)/UserManual.qhcp: $$(VBOX_PATH_MANUAL_SRC)/UserManual.qhcp | $$$$(dir $$$$@) 884 $$(QUIET)$$(INSTALL_STAGING) -m0644 -- '$$<' '$$(@D)' 885 886 # 4. Run the Qt help generator to produce the .qhp and .qch files. 887 $(2)/UserManual.qch \ 888 + $(2)/UserManual.qhc: \ 889 $(2)/UserManual.qhcp \ 890 $(2)/UserManual.qhp \ 891 | $$$$(dir $$$$@) 892 $$(call MSG_L1,$$(notdir $$(VBOX_QHELPGENERATOR)) $$<,=> $$@) 893 $$(QUIET)$$(RM) -f $$@ 894 ifdef VBOX_WITH_QT6 895 $$(QUIET)$$(REDIRECT) -- $$(VBOX_QHELPGENERATOR) $$< 896 else 897 $$(QUIET)$$(REDIRECT) -E QT_QPA_PLATFORM_PLUGIN_PATH=$$(PATH_SDK_QT5)/plugins -- $$(VBOX_QHELPGENERATOR) $$< 898 endif 899 $$(call MSG_L1,Fresh QCH is now at $$@) 900 901 endef # def_vbox_usermanual_as_qhelp 902 903 $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES) \ 904 ,$(evalcall2 def_vbox_usermanual_as_qhelp,$(lang),$(VBOX_PATH_MANUAL_OUTBASE)/$(lang)/qhelp)) 905 906 qhelp:: $(addprefix $(VBOX_PATH_MANUAL_OUTBASE)/en_US/qhelp/, $(VBOX_QHELP_OUTPUT_FILES)) 907 908 endif # VBOX_WITH_DOCS_QHELP && !VBOX_ONLY_SDK 909 910 911 ################################################################################################################################# 912 # Miscellaneous # 913 ################################################################################################################################# 914 854 915 # 855 916 # ChangeLog.html … … 870 931 871 932 cl-html:: $(VBOX_PATH_MANUAL_OUTBASE)/en_US/ChangeLog.html 872 873 933 874 934 … … 925 985 926 986 927 if defined(VBOX_WITH_DOCS_QHELP) && !defined(VBOX_ONLY_SDK)928 #929 # VirtualBox.qch/VirtualBox.qhc930 #931 # We first generate a .hhp help source file from the preprocessed932 # DocBook XML files, as defined above, then feed that into a converter933 # creating the suitable input for creating a QHelp collection file.934 #935 936 # Enable Qt and locate the Qt help generator.937 ifdef VBOX_WITH_QT6938 USES += qt6939 VBOX_QHELPGENERATOR = $(PATH_TOOL_QT6_LIBEXEC)/qhelpgenerator940 else941 USES += qt5942 VBOX_QHELPGENERATOR_VERSION_MINOR = $(shell $(REDIRECT) -E QT_QPA_PLATFORM_PLUGIN_PATH=$(PATH_SDK_QT5)/plugins -- $(PATH_TOOL_QT5_BIN)/qhelpgenerator -v 2>/dev/null | $(SED) -ne 's/.*(Qt [1-9][0-9]*\.\([1-9][0-9]*\)\.[1-9][0-9]*).*$$/\1/p')943 VBOX_QHELPGENERATOR = $(PATH_TOOL_QT5_BIN)/$(if-expr $(VBOX_QHELPGENERATOR_VERSION_MINOR) >= 12,qhelpgenerator,qcollectiongenerator)944 endif945 946 # Generate QCH from QHelp source947 # Note: out_dir referenced with double $$ to delay expansion to the eval step when out_dir has been defined.948 define def_vbox_usermanual_qhp_to_qch949 local out_dir := $(VBOX_PATH_MANUAL_OUTBASE)/$(lang)950 $$(out_dir)/qhelp/UserManual.qch \951 + $$(out_dir)/qhelp/UserManual.qhc: \952 $$(out_dir)/qhelp/UserManual.qhcp \953 $$(out_dir)/qhelp/UserManual.qhp \954 $$(addprefix $$(out_dir)/qhelp/,$$(VBOX_MANUAL_PNG_FILES_$(lang))) \955 | $$$$(dir $$$$@)956 $$(call MSG_L1,$$(notdir $$(VBOX_QHELPGENERATOR)) $$<,=> $$@)957 $$(QUIET)$$(RM) -f $$@958 $$(QUIET)$$(REDIRECT) -E QT_QPA_PLATFORM_PLUGIN_PATH=$$(PATH_SDK_QT5)/plugins -- $$(VBOX_QHELPGENERATOR) $$<959 $$(call MSG_L1,Fresh QCH is now at $$@)960 endef961 $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES),$(evalcall2 def_vbox_usermanual_qhp_to_qch))962 963 # Generate QHP from HHP for QHelp964 # Note: out_dir referenced with double $$ to delay expansion to the eval step when out_dir has been defined.965 define def_vbox_usermanual_hhp_qhelp_to_qhp966 local out_dir := $(VBOX_PATH_MANUAL_OUTBASE)/$(lang)967 $$(out_dir)/qhelp/UserManual.qhp: \968 $$(out_dir)/qhelp/UserManual.hhp \969 $$(addprefix $$(out_dir)/qhelp/,$$(VBOX_MANUAL_PNG_FILES_$(lang))) \970 | $$$$(dir $$$$@)971 $$(call MSG_L1,htmlhelp-qthelp.py $$<,=> $$@)972 $$(QUIET)$$(RM) -f $$@973 $$(QUIET)$$(VBOX_BLD_PYTHON) $$(VBOX_PATH_MANUAL_SRC)/htmlhelp-qthelp.py -d $$(<D) -o $$@ -f UserManual.hhp -t UserManual.hhc974 endef975 $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES),$(evalcall2 def_vbox_usermanual_hhp_qhelp_to_qhp))976 977 # Setting HHCDIR here so that it fails to locate hcc.exe and always skips the978 # compilation step that produces the .chm-file, since we don't need it and it979 # mangles the path so it always fails anyway.980 define def_ditamap_to_htmlhelp981 ditamap-to-htmlhelp: $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/qhelp/UserManual.hhp982 $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/qhelp/UserManual.hhp: \983 $(VBOX_USER_MANUAL_DITA_STAGED_FILES_$(1)) \984 $(VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES_$(1))985 $$(QUIET)$(RM) -Rf -- "$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita-ot-qhelp/"986 $$(QUIET)$$(call VBOX_DITA_RUN_DOST,$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita-ot-qhelp, -EHHCDIR="$$(@D)") \987 "/i:$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/UserManual.ditamap" \988 "/transtype:htmlhelp" \989 "/outdir:$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/qhelp" \990 "/tempdir:$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/temp_htmlhelp"991 992 endef993 $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES),$(evalcall2 def_ditamap_to_htmlhelp,$(lang)))994 995 # copy the qhcp file.996 define def_vbox_cp_qhcp997 local out_dir := $(VBOX_PATH_MANUAL_OUTBASE)/$(lang)/qhelp998 $$(out_dir)/UserManual.qhcp: \999 $$(out_dir)/% : $(VBOX_PATH_MANUAL_SRC)/% | $$$$(dir $$$$@)1000 $$(QUIET)$$(INSTALL_STAGING) -m0644 -- '$$<' '$$(@D)'1001 endef1002 $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES),$(eval $(def_vbox_cp_qhcp)))1003 1004 # copy the PNG files.1005 # Note: out_dir referenced with double $$ to delay expansion to the eval step when out_dir has been defined.1006 define def_vbox_cp_images_qhelp1007 local out_dir := $(VBOX_PATH_MANUAL_OUTBASE)/$(lang)/qhelp1008 $(addprefix $$(out_dir)/,$(VBOX_MANUAL_PNG_FILES_$(lang))): \1009 $$(out_dir)/% : $(VBOX_PATH_MANUAL_SRC)/$(lang)/% | $$$$(dir $$$$@)1010 $$(call MSG_L1,Copying temporary $$< => $$@)1011 $$(QUIET)$$(INSTALL_STAGING) -m0644 -- '$$<' '$$(@D)'1012 endef1013 $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES),$(eval $(def_vbox_cp_images_qhelp)))1014 1015 endif # VBOX_WITH_DOCS_QHELP && !VBOX_ONLY_SDK1016 1017 1018 987 # 1019 988 # Packing the docs into a zip file (part of the packing pass on the docs build box). -
trunk/doc/manual/htmlhelp-qthelp.py
r98950 r99064 1 1 #!/usr/bin/python3 2 2 # -*- coding: utf-8 -*- 3 3 # $Id$ 4 ## @file 5 # A python script to create a .qhp file out of a given htmlhelp 6 # folder. Lots of things about the said folder is assumed. Please 7 # see the code and inlined comments. 8 9 import sys, getopt 10 import os.path 11 import re 12 import logging 13 14 if sys.version_info >= (3, 0): 15 from html.parser import HTMLParser 16 else: 17 from HTMLParser import HTMLParser 18 19 4 5 """ 6 A python script to create a .qhp file out of a given htmlhelp 7 folder. Lots of things about the said folder is assumed. Please 8 see the code and inlined comments. 9 """ 20 10 21 11 __copyright__ = \ … … 42 32 """ 43 33 34 import getopt 35 import logging 36 import os.path 37 import re 38 import sys 39 40 if sys.version_info[0] >= 3: 41 from html.parser import HTMLParser 42 else: 43 from HTMLParser import HTMLParser 44 44 45 # number of opened and not yet closed section tags of toc section 45 46 open_section_tags = 0 … … 47 48 html_files = [] 48 49 49 # use html_parser stuff to collect <a name tags50 50 def create_keywords_section(folder): 51 """ 52 use html_parser stuff to collect <a name ...> tags 53 """ 51 54 keywords_section_lines = ['<keywords>'] 52 55 for html_file_name in html_files: … … 55 58 56 59 class html_parser(HTMLParser): 57 def __init__(self):58 HTMLParser.__init__(self)59 self.a_tag=[]60 def handle_starttag(self, tag, attributes):61 if tag != 'div' and tag != 'a':62 return63 if tag == 'a':64 for a in attributes:65 if a[0] == 'name':66 self.a_tag.append(a[1])60 def __init__(self): 61 HTMLParser.__init__(self) 62 self.a_tag = [] 63 def handle_starttag(self, tag, attrs): 64 if tag != 'div' and tag != 'a': 65 return 66 if tag == 'a': 67 for a in attrs: 68 if a[0] == 'name': 69 self.a_tag.append(a[1]) 67 70 68 71 parser = html_parser() … … 70 73 for k in parser.a_tag: 71 74 line = '<keyword name="' + k + '" id="' + k + '" ref="' + html_file_name + '#' + k + '"/>' 72 keywords_section_lines.append(line) ;75 keywords_section_lines.append(line) 73 76 keywords_section_lines.append('</keywords>') 74 77 return keywords_section_lines 75 78 76 # find the png files under /images folder and create a part of the77 # qhelp project file with <file> tags78 79 def create_image_list(folder): 79 image_folder_name = 'images' 80 image_files_list = [] 81 # Look for 'images' sub folder 82 subdirs = [x[0] for x in os.walk(folder)] 83 full_folder_path = os.path.join(folder, image_folder_name) 84 if full_folder_path not in subdirs: 85 logging.error('Image subfolder "%s" is not found under "%s".', image_folder_name, folder) 86 return image_files_list; 87 png_files = [] 88 for f in os.listdir(full_folder_path): 89 png_files.append(image_folder_name + '/' + f) 90 image_files_list.append('<file>images/' + f + '</file>') 91 return image_files_list 92 93 # open files list and read the list of html files from there 80 """ 81 find the png files under topics/images folder and create a part of the 82 qhelp project file with <file> tags 83 """ 84 sFullImageFolderPath = os.path.join(folder, 'topics', 'images'); 85 if not os.path.isdir(sFullImageFolderPath): 86 logging.error('Image subfolder "topics/images" is not found under "%s"!', folder) 87 sys.exit(1); 88 return ['<file>topics/images/%s</file>' % sFile for sFile in os.listdir(sFullImageFolderPath)]; 89 94 90 def create_html_list(folder, list_file): 91 """ 92 open files list and read the list of html files from there 93 """ 95 94 global html_files 96 95 html_file_lines = [] … … 99 98 return html_file_lines 100 99 full_path = os.path.join(folder, list_file) 101 file = open(full_path, encoding='utf-8') 102 103 lines = file.readlines() 104 file.close() 100 with open(full_path, encoding='utf-8') as file: 101 lines = file.readlines() 102 105 103 # first search for the [FILES] marker then collect .html lines 106 104 marker_found = 0 … … 126 124 def parse_param_tag(line): 127 125 label = 'value="' 128 start = line.find(label) ;126 start = line.find(label) 129 127 if start == -1: 130 128 return '' 131 start += 129 start += len(label) 132 130 end = line.find('"', start) 133 131 if end == -1: 134 return '' ;132 return '' 135 133 return line[start:end] 136 134 137 # look at next two lines. they are supposed to look like the following138 # <param name="Name" value="Oracle VM VirtualBox">139 # <param name="Local" value="index.html">140 # parse out value fields and return141 # title="Oracle VM VirtualBox" ref="index.html142 135 def parse_object_tag(lines, index): 143 result='' 136 """ 137 look at next two lines. they are supposed to look like the following 138 <param name="Name" value="Oracle VM VirtualBox"> 139 <param name="Local" value="index.html"> 140 parse out value fields and return 141 title="Oracle VM VirtualBox" ref="index.html 142 """ 143 result = '' 144 144 if index + 2 > len(lines): 145 logging.warning('Not enough tags after this one "%s"', lines[index])145 logging.warning('Not enough tags after this one "%s"', lines[index]) 146 146 return result 147 if not re.match(r'^\s*<param', lines[index + 1], re.IGNORECASE) or\148 not re.match(r'^\s*<param', lines[index + 2], re.IGNORECASE):149 logging.warning('Skipping the line "%s" since next two tags are supposed to be param tags', 147 if not re.match(r'^\s*<param', lines[index + 1], re.IGNORECASE) \ 148 or not re.match(r'^\s*<param', lines[index + 2], re.IGNORECASE): 149 logging.warning('Skipping the line "%s" since next two tags are supposed to be param tags', lines[index]) 150 150 return result 151 151 title = parse_param_tag(lines[index + 1]) … … 159 159 return result 160 160 161 # parse any string other than staring with <OBJECT162 # decide if <session tag should be closed163 161 def parse_non_object_tag(lines, index): 162 """ 163 parse any string other than staring with <OBJECT 164 decide if <section> tag should be closed 165 """ 166 164 167 if index + 1 > len(lines): 165 168 return '' … … 178 181 179 182 def parse_line(lines, index): 180 result =''183 result = '' 181 184 182 185 # if the line starts with <OBJECT … … 187 190 return result 188 191 189 # parse TOC file. assuming all the relevant information190 # is stored in tags and attributes. whatever is outside of191 # <... > pairs is filtered out. we also assume < ..> are not nested192 # and each < matches to a >193 192 def create_toc(folder, toc_file): 193 """ 194 parse TOC file. assuming all the relevant information 195 is stored in tags and attributes. whatever is outside of 196 <... > pairs is filtered out. we also assume < ..> are not nested 197 and each < matches to a > 198 """ 194 199 toc_string_list = [] 195 200 content = [x[2] for x in os.walk(folder)] … … 198 203 return toc_string_list 199 204 full_path = os.path.join(folder, toc_file) 200 file = open(full_path, encoding='utf-8')201 content = file.read()202 file.close() 205 with open(full_path, encoding='utf-8') as file: 206 content = file.read() 207 203 208 # convert the file string into a list of tags there by eliminating whatever 204 209 # char reside outside of tags. … … 219 224 # lines = content.split('\n') 220 225 toc_string_list.append('<toc>') 221 index = 0 222 for tag in tag_list: 226 for index, _ in enumerate(tag_list): 223 227 str = parse_line(tag_list, index) 224 228 if str: 225 229 toc_string_list.append(str) 226 index += 1227 230 toc_string_list.append('</toc>') 228 231 toc_string = '\n'.join(toc_string_list) … … 230 233 return toc_string_list 231 234 232 def usage( arg):235 def usage(iExitCode): 233 236 print('htmlhelp-qthelp.py -d <helphtmlfolder> -o <outputfilename>') 234 sys.exit()237 return iExitCode 235 238 236 239 def main(argv): 240 # Parse arguments. 237 241 helphtmlfolder = '' 238 242 output_filename = '' … … 240 244 toc_file = '' 241 245 try: 242 opts, args = getopt.getopt(sys.argv[1:],"hd:o:f:t:")246 opts, _ = getopt.getopt(argv[1:], "hd:o:f:t:") 243 247 except getopt.GetoptError as err: 244 print(err)245 usage(2)248 logging.error(str(err)) 249 return usage(2) 246 250 for opt, arg in opts: 247 251 if opt == '-h': 248 usage(0)249 elif opt in ("-d"):252 return usage(0) 253 if opt == "-d": 250 254 helphtmlfolder = arg 251 255 print(helphtmlfolder) 252 elif opt in ("-f"):256 elif opt == "-f": 253 257 list_file = arg 254 elif opt in ("-t"):258 elif opt == "-t": 255 259 toc_file = arg 256 260 print(toc_file) 257 elif opt in ("-o"):258 261 elif opt == "-o": 262 output_filename = arg 259 263 # check supplied helphtml folder argument 260 264 if not helphtmlfolder: 261 265 logging.error('No helphtml folder is provided. Exiting') 262 usage(2)266 return usage(2) 263 267 if not os.path.exists(helphtmlfolder): 264 268 logging.error('folder "%s" does not exist. Exiting', helphtmlfolder) 265 usage(2)269 return usage(2) 266 270 helphtmlfolder = os.path.normpath(helphtmlfolder) 267 271 … … 269 273 if not output_filename: 270 274 logging.error('No filename for output is given. Exiting') 271 usage(2)272 273 out_xml_lines = ['<?xml version="1.0" encoding="UTF-8"?>', \274 '<QtHelpProject version="1.0">' , \275 '<namespace>org.virtualbox</namespace>', \276 '<virtualFolder>doc</virtualFolder>', \275 return usage(2) 276 277 out_xml_lines = ['<?xml version="1.0" encoding="UTF-8"?>', 278 '<QtHelpProject version="1.0">', 279 '<namespace>org.virtualbox</namespace>', 280 '<virtualFolder>doc</virtualFolder>', 277 281 '<filterSection>'] 278 out_xml_lines += create_toc(helphtmlfolder, toc_file) + create_files_section(helphtmlfolder, list_file) 282 out_xml_lines += create_toc(helphtmlfolder, toc_file) 283 out_xml_lines += create_files_section(helphtmlfolder, list_file) 279 284 out_xml_lines += create_keywords_section(helphtmlfolder) 280 285 out_xml_lines += ['</filterSection>', '</QtHelpProject>'] 281 286 282 out_file = open(output_filename, 'wb')283 out_file.write('\n'.join(out_xml_lines).encode('utf8'))284 out_file.close()287 with open(output_filename, 'wb') as out_file: 288 out_file.write('\n'.join(out_xml_lines).encode('utf8')) 289 return 0 285 290 286 291 if __name__ == '__main__': 287 main(sys.argv[1:])292 sys.exit(main(sys.argv))
Note:
See TracChangeset
for help on using the changeset viewer.