self._settingsHeaderRow = None\r
#: The number of layouts for settings in a settings section.\r
self._settingsNumLayouts = 0\r
+ #: The current line number being processed, used to present location of syntax errors\r
+ self._lineNum = 0\r
\r
def make(self):\r
"""Generate the Key Commands document.\r
\r
def _make(self):\r
for line in self._ug:\r
+ self._lineNum += 1\r
line = line.rstrip()\r
m = self.RE_COMMAND.match(line)\r
if m:\r
# Handle header commands.\r
if cmd == "title":\r
if self._kcSect > self.KCSECT_HEADER:\r
- raise KeyCommandsError("title command is not valid here")\r
+ raise KeyCommandsError("%d, title command is not valid here" % self._lineNum)\r
# Write the title and two blank lines to complete the txt2tags header section.\r
self._kc.write(arg + LINE_END * 3)\r
self._kcSect = self.KCSECT_CONFIG\r
self._kc.write("%%!includeconf: ../global.t2tconf%s" % LINE_END)\r
return\r
elif self._kcSect == self.KCSECT_HEADER:\r
- raise KeyCommandsError("title must be the first command")\r
+ raise KeyCommandsError("%d, title must be the first command" % self._lineNum)\r
elif cmd == "includeconf":\r
if self._kcSect > self.KCSECT_CONFIG:\r
- raise KeyCommandsError("includeconf command is not valid here")\r
+ raise KeyCommandsError("%d, includeconf command is not valid here" % self._lineNum)\r
self._kc.write("%%!includeconf: %s%s" % (arg, LINE_END))\r
return\r
elif self._kcSect == self.KCSECT_CONFIG:\r
self._handleSetting()\r
\r
else:\r
- raise KeyCommandsError("Invalid command %s" % cmd)\r
+ raise KeyCommandsError("%d, Invalid command %s" % (self._lineNum, cmd))\r
\r
def _areHeadingsPending(self):\r
return self._kcLastHeadingLevel < len(self._headings) - 1\r
\r
def _handleSetting(self):\r
if not self._settingsHeaderRow:\r
- raise KeyCommandsError("setting command cannot be used before settingsSection command")\r
+ raise KeyCommandsError("%d, setting command cannot be used before settingsSection command" % self._lineNum)\r
\r
if self._areHeadingsPending():\r
# There are new headings to write.\r
\r
# The next line should be a heading which is the name of the setting.\r
line = next(self._ug)\r
+ self._lineNum += 1\r
m = self.t2tRe["title"].match(line)\r
if not m:\r
- raise KeyCommandsError("setting command must be followed by heading")\r
+ raise KeyCommandsError("%d, setting command must be followed by heading" % self._lineNum)\r
name = m.group("txt")\r
\r
# The next few lines should be table rows for each layout.\r
keys = []\r
for layout in xrange(self._settingsNumLayouts):\r
line = next(self._ug).strip()\r
+ self._lineNum += 1\r
if ":" in line:\r
keys.append(line.split(":", 1)[1].strip())\r
break\r
elif not self.t2tRe["table"].match(line):\r
- raise KeyCommandsError("setting command: There must be one table row for each keyboard layout")\r
+ raise KeyCommandsError("%d, setting command: There must be one table row for each keyboard layout" % self._lineNum)\r
# This is a table row.\r
# The key will be the second column.\r
# TODO: Error checking.\r
\r
# There should now be a blank line.\r
line = next(self._ug).strip()\r
+ self._lineNum += 1\r
if line:\r
- raise KeyCommandsError("setting command: The keyboard shortcuts must be followed by a blank line. Multiple keys must be included in a table. Erroneous key: %s"%key)\r
+ raise KeyCommandsError("%d, setting command: The keyboard shortcuts must be followed by a blank line. Multiple keys must be included in a table. Erroneous key: %s" % (self._lineNum, key))\r
\r
# Finally, the next line should be the description.\r
desc = next(self._ug).strip()\r
+ self._lineNum += 1\r
\r
self._kc.write(u"| {name} | {keys} | {desc} |{lineEnd}".format(\r
name=name,\r