1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
# -*- coding: utf-8 -*-
# $Id: add_file_to_id_only_references.py $
"""
Makes id-only reference in the given file into dita-compliant file#id
references, using the mapping database generated by build_id_to_file_mapping.py.
"""
__copyright__ = \
"""
Copyright (C) 2023-2024 Oracle and/or its affiliates.
This file is part of VirtualBox base platform packages, as
available from https://www.virtualbox.org.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, in version 3 of the
License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <https://www.gnu.org/licenses>.
SPDX-License-Identifier: GPL-3.0-only
"""
__version__ = "$Revision: 164827 $"
# Standard python imports.
import glob;
import os;
import re;
import sys;
g_oReHref = re.compile(r'\bhref=("[^">#./]+"|\'[^\'>#./]+\')');
def modifyDitaFile(dIdToFile, sContent):
"""
Modifies the href attributes in this file.
"""
sModified = '';
offPrev = 0;
for oMatch in g_oReHref.finditer(sContent):
sId = oMatch.group(1)[1:-1];
if sId in dIdToFile:
sModified += sContent[offPrev : oMatch.start(1)] + '"' + dIdToFile[sId] + '#' + sId + '"';
offPrev = oMatch.end(1);
if offPrev < len(sContent):
sModified += sContent[offPrev:];
return sModified;
def info(sMessage):
""" Info message. """
print('add_file_to_id_only_references.py: info: %s' % sMessage);
return 1;
def error(sMessage):
""" Reports an error. """
print('add_file_to_id_only_references.py: error: %s' % sMessage, file = sys.stderr);
return 1;
def syntax(sMessage):
""" Reports a syntax error. """
print('add_file_to_id_only_references.py: syntax error: %s' % sMessage, file = sys.stderr);
return 2;
def usage():
""" Reports usage. """
print('usage: add_file_to_id_only_references.py [--verbose|--quiet] --mapping-file <map.db> file1.dita [file2.dita [...]]');
return 0;
def main(asArgs):
"""
C-like main function.
"""
#
# Process arguments.
#
dIdToFile = None;
fEndOfArgs = False;
fVerbose = False;
iArg = 1;
while iArg < len(asArgs):
sArg = asArgs[iArg];
if sArg[0] == '-' and not fEndOfArgs:
# Options.
if sArg == '--':
fEndOfArgs = True;
elif sArg in ('--help', '-h', '-?'):
return usage();
elif sArg in ('--version', '-V' ):
print(__version__[__version__.find(':') + 2:-2]);
elif sArg in ('--quiet', '-q' ):
fVerbose = False;
elif sArg in ('--verbose', '-v' ):
fVerbose = True;
elif sArg in ('--mapping-file', '-m'):
iArg += 1;
if iArg >= len(asArgs):
return syntax('Expected filename following "--mapping-file"!');
# Load the database file.
sArg = asArgs[iArg];
try:
with open(sArg, 'r', encoding = 'utf-8') as oFile:
dIdToFile = {};
for sLine in oFile:
sId, sFile = sLine.split('=');
dIdToFile[sId.strip()] = sFile.strip();
except Exception as oXcpt: # pylint: disable=broad-exception-caught
return error('Failed to open and parse "%s": %s' % (sArg, oXcpt,));
if fVerbose:
info('Loaded %s IDs from "%s"' % (len(dIdToFile), sArg));
else:
return syntax('Unknown option: %s' % (sArg,));
else:
# File to modify.
if dIdToFile is None:
return syntax('A mapping database must be given before any other files!');
try:
with open(sArg, 'r', encoding = 'utf-8') as oFile:
sContent = oFile.read();
except Exception as oXcpt: # pylint: disable=broad-exception-caught
return error('Failed to open and read "%s": %s' % (sArg, oXcpt,));
sModified = modifyDitaFile(dIdToFile, sContent);
if sModified != sContent:
if fVerbose:
info('Writing out modified "%s"...' % (sArg,));
try:
with open(sArg, 'w', encoding = 'utf-8') as oFile:
oFile.write(sModified);
except Exception as oXcpt: # pylint: disable=broad-exception-caught
return error('Failed to open and write back "%s": %s' % (sArg, oXcpt,));
elif fVerbose:
info('No changes to "%s"...' % (sArg,));
iArg += 1;
return 0;
if __name__ == "__main__":
sys.exit(main(sys.argv));
|