def variablerule(text, variable, caseSensitive=False): """Generates an error rule that checks to see if an element contains a piece of text that should really be a Flare variable.""" if caseSensitive: normalizedText = ' '.join(text.split()) normalizedTest = lambda n: normalizedText not in ' '.join(n.text(). split()) else: normalizedText = ' '.join(text.split()).casefold() normalizedTest = lambda n: normalizedText not in ' '.join(n.text( ).split()).casefold() rule.Error(extensions=rule.TOPICS_AND_SNIPPETS, match=lambda n: not n.ancestor_or_self( '*', lambda n: n.name() in _ACCEPTED_ANCESTORS_VAR), test=normalizedTest, message="""The text """ + rule.LDQUO + """`""" + text + """`""" + rule.RDQUO + """ instead of its variable. We ensure consistency and simplify maintenance by using a variable for this text instead. To fix, replace this text with variable `""" + variable + """`.""")
# # The contents of this file are subject to the terms of the # Common Development and Distribution License, Version 1.0 only # (the "License"). You may not use this file except in compliance # with the License. # # The full text of the License is in LICENSE.txt. See the License # for the specific language governing permissions and limitations # under the License. # # When distributing Covered Software, include this CDDL HEADER in # each file and include LICENSE.txt. If applicable, add the # following below this CDDL HEADER, with the fields enclosed by # brackets "[]" replaced with your own identifying information: # Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END from flarelint import rule from flarelint import flarenode rule.Error( extensions=rule.TOPICS_AND_SNIPPETS, match=flarenode.whenself('MadCap:xref'), test=lambda n: '#' not in n.attribute('href'), message="""Cross-reference to a location in the same topic or to a specific element inside another topic. Our write style allows cross-references to link only to an entire topic file. To fix, restructure or link the cross-references to another topic (in the same project).""")
# # The full text of the License is in LICENSE.txt. See the License # for the specific language governing permissions and limitations # under the License. # # When distributing Covered Software, include this CDDL HEADER in # each file and include LICENSE.txt. If applicable, add the # following below this CDDL HEADER, with the fields enclosed by # brackets "[]" replaced with your own identifying information: # Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END from flarelint import rule from flarelint import flarenode rule.Error( extensions = rule.TOPICS_AND_SNIPPETS, match = flarenode.whenself('ul'), test = lambda n: not n.child('li', lambda n: n.child('p', lambda n: n.position() > 0)), message = """Too many paragraphs in a list item (`li`) of a bullet list (`ul`). Our writing convention is for a single paragraph in a bullet list item (`li`). To fix, move the extra paragraphs to separate list items, consider using sections (`h2.Section` elements), or consider using a table.""" )
# for the specific language governing permissions and limitations # under the License. # # When distributing Covered Software, include this CDDL HEADER in # each file and include LICENSE.txt. If applicable, add the # following below this CDDL HEADER, with the fields enclosed by # brackets "[]" replaced with your own identifying information: # Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END from flarelint import rule from flarelint import flarenode _ACCEPTED_EMPTY_P_DESC = [ 'img', 'iframe', 'MadCap:snippetText', 'MadCap:variable' ] _ACCEPTED_EMPTY_P_ANC = ['td'] rule.Error( extensions=rule.TOPICS_AND_SNIPPETS, match=lambda n: n.iselement('p') and n.valueof().strip() == '', test=lambda n: n.ancestor('*', lambda n: n.name() in _ACCEPTED_EMPTY_P_ANC) or n.descendant('*', lambda n: n.name() in _ACCEPTED_EMPTY_P_DESC), message="""Empty paragraph. A `p` element must not be empty. To fix, delete it. *Note:* Empty paragraphs are permitted in """ + ", ".join("`{0}`".format(e) for e in _ACCEPTED_EMPTY_P_ANC) + """ elements.""")
# # The contents of this file are subject to the terms of the # Common Development and Distribution License, Version 1.0 only # (the "License"). You may not use this file except in compliance # with the License. # # The full text of the License is in LICENSE.txt. See the License # for the specific language governing permissions and limitations # under the License. # # When distributing Covered Software, include this CDDL HEADER in # each file and include LICENSE.txt. If applicable, add the # following below this CDDL HEADER, with the fields enclosed by # brackets "[]" replaced with your own identifying information: # Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END from flarelint import rule from flarelint import flarenode rule.Error( extensions=rule.TOPICS, # Match only the first title, ignore others. Multiple h1 elements # are handled by other rules. match=lambda n: n.iselement('h1') and not n.precedingsibling('h1'), test=lambda n: n.indexof() == 0, message="""Topic body must start with an `h1` element. To fix, move the `h1` element to the top of the body.""")
# # Copyright 2016-2017 Intelerad Medical Systems Incorporated. All # rights reserved. # # The contents of this file are subject to the terms of the # Common Development and Distribution License, Version 1.0 only # (the "License"). You may not use this file except in compliance # with the License. # # The full text of the License is in LICENSE.txt. See the License # for the specific language governing permissions and limitations # under the License. # # When distributing Covered Software, include this CDDL HEADER in # each file and include LICENSE.txt. If applicable, add the # following below this CDDL HEADER, with the fields enclosed by # brackets "[]" replaced with your own identifying information: # Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END from flarelint import rule from flarelint import flarenode rule.Error( extensions=rule.TOPICS, match=flarenode.whenself('h1'), test=lambda n: not n.precedingsibling('h1'), message="""Too many `h1` titles. A topic may contain only one title. To fix, restructure the topic or create separate sub-topic files.""")
# rights reserved. # # The contents of this file are subject to the terms of the # Common Development and Distribution License, Version 1.0 only # (the "License"). You may not use this file except in compliance # with the License. # # The full text of the License is in LICENSE.txt. See the License # for the specific language governing permissions and limitations # under the License. # # When distributing Covered Software, include this CDDL HEADER in # each file and include LICENSE.txt. If applicable, add the # following below this CDDL HEADER, with the fields enclosed by # brackets "[]" replaced with your own identifying information: # Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END from flarelint import rule from flarelint import flarenode _HARDCODE_STYLES = ['b', 'u', 'i'] rule.Error( extensions=rule.TOPICS_AND_SNIPPETS, match=lambda n: n.name() in _HARDCODE_STYLES, test=lambda n: False, message="""Hard-coded formatting. What do you mean? To fix, use semantic stylesheet classes instead.""")
# # Copyright 2016-2017 Intelerad Medical Systems Incorporated. All # rights reserved. # # The contents of this file are subject to the terms of the # Common Development and Distribution License, Version 1.0 only # (the "License"). You may not use this file except in compliance # with the License. # # The full text of the License is in LICENSE.txt. See the License # for the specific language governing permissions and limitations # under the License. # # When distributing Covered Software, include this CDDL HEADER in # each file and include LICENSE.txt. If applicable, add the # following below this CDDL HEADER, with the fields enclosed by # brackets "[]" replaced with your own identifying information: # Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END from flarelint import rule from flarelint import flarenode rule.Error( extensions=rule.TOPICS_AND_SNIPPETS, match=flarenode.whenself('div'), test=lambda n: not n.style('div'), message="""Text box with missing style class. What kind of text box is this? To fix, apply a style.""")
_ACCEPTED_ENDING_FR = ' ;' _ACCEPTED_ENDING_LAST_FR = '.' _RE_FR = r'{0}\s*$'.format("".join("[{0}]".format(x) for x in _ACCEPTED_ENDING_FR)) _RE_LAST_FR = r'{0}\s*$'.format("".join("[{0}]".format(x) for x in _ACCEPTED_ENDING_LAST_FR)) rule.Error( extensions=rule.TOPICS_AND_SNIPPETS, match=lambda n: n.iselement('li') and n.parent('ul') and n.lang('en'), test=lambda n: not n.nextsibling('li') or (re.search(_RE_EN, n.valueof( )) and re.search(_RE_EN, n.nextsibling('li').valueof())) or (not re.search(_RE_EN, n.valueof()) and not re.search( _RE_EN, n.nextsibling('li').valueof())), message="""Inconsistent punctuation in a bullet list (`ul`). All items in a list must consistently use uncapitalized phrases (except, of course, product and proper names) with no ending punctuation, or full sentences with first words capitalized and ending punctuation. Accepted ending punctuation is """ + rule.LDQUO + _ACCEPTED_PUNCT_EN + rule.RDQUO + """. To fix, adjust the capitalization and punctuation. """) rule.Error( extensions=rule.TOPICS_AND_SNIPPETS, match=lambda n: n.iselement('li') and n.nextsibling('li') and n.parent( 'ul') and n.lang('fr'), test=lambda n: re.search(_RE_FR, n.valueof()), message="""Incorrect punctuation in a bullet list (`ul`). Each item, except the last, in a bullet list must be an uncapitalized phrase
# with the License. # # The full text of the License is in LICENSE.txt. See the License # for the specific language governing permissions and limitations # under the License. # # When distributing Covered Software, include this CDDL HEADER in # each file and include LICENSE.txt. If applicable, add the # following below this CDDL HEADER, with the fields enclosed by # brackets "[]" replaced with your own identifying information: # Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END from flarelint import rule from flarelint import flarenode _ACCEPTED_EMPTY_LI = ['img', 'iframe', 'MadCap:snippetText', 'MadCap:variable'] rule.Error( extensions = rule.TOPICS_AND_SNIPPETS, match = lambda n: n.iselement('li') and n.valueof().strip() == '', test = lambda n: n.descendant('*', lambda n: n.name() in _ACCEPTED_EMPTY_LI), message = """Empty list item. An `li` element must not be empty. To fix, delete it.""" )
def targeterror(test, message, outputType=None): rule.Error(extensions=rule.TARGETS, match=lambda n: n.iselement('CatapultTarget') and (n.attribute('Type') == outputType or outputType is None), test=test, message=message)
# (the "License"). You may not use this file except in compliance # with the License. # # The full text of the License is in LICENSE.txt. See the License # for the specific language governing permissions and limitations # under the License. # # When distributing Covered Software, include this CDDL HEADER in # each file and include LICENSE.txt. If applicable, add the # following below this CDDL HEADER, with the fields enclosed by # brackets "[]" replaced with your own identifying information: # Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END from flarelint import rule from flarelint import flarenode _HEADINGS_ACCEPTED = set(['h1', 'h2']) _HEADINGS_ALL = set(['h1', 'h2', 'h3', 'h4', 'h5', 'h6']) rule.Error( extensions=rule.TOPICS_AND_SNIPPETS, # This match function is also the test, so the test function always fails. match=lambda n: n.name() in _HEADINGS_ALL.difference(_HEADINGS_ACCEPTED), test=lambda n: False, message="""Unsupported header. This level of header is not supported by our conventions or styles. To fix, place a subtopic in a separate file.""")
# for the specific language governing permissions and limitations # under the License. # # When distributing Covered Software, include this CDDL HEADER in # each file and include LICENSE.txt. If applicable, add the # following below this CDDL HEADER, with the fields enclosed by # brackets "[]" replaced with your own identifying information: # Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END from flarelint import rule from flarelint import flarenode import os _ACCEPTED_FORMATS = ['.png', '.jpg', '.jpeg'] rule.Error( extensions = rule.TOPICS_AND_SNIPPETS, match = flarenode.whenself('img'), test = lambda n: os.path.splitext(n.attribute('src'))[1].lower() in _ACCEPTED_FORMATS, message = """Unsupported graphics format. To fix, convert this file to an accepted format (""" + ", ".join(["`{0}`".format(s) for s in _ACCEPTED_FORMATS]) + """), revise the link to the new graphics file, and delete the unsupported file.""" )
# # The contents of this file are subject to the terms of the # Common Development and Distribution License, Version 1.0 only # (the "License"). You may not use this file except in compliance # with the License. # # The full text of the License is in LICENSE.txt. See the License # for the specific language governing permissions and limitations # under the License. # # When distributing Covered Software, include this CDDL HEADER in # each file and include LICENSE.txt. If applicable, add the # following below this CDDL HEADER, with the fields enclosed by # brackets "[]" replaced with your own identifying information: # Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END from flarelint import rule from flarelint import flarenode rule.Error( extensions=rule.TOPICS_AND_SNIPPETS, match=flarenode.whenself('h1'), test=lambda n: (not '\n' in n.valueof()) or n.child('br'), message= """Hidden line break. This line break could cause a broken page header in PDF. To fix, open the topic in the text editor (raw XML) and make sure that the contents of the `h1` element are all on one line.""")
# # Copyright 2016-2017 Intelerad Medical Systems Incorporated. All # rights reserved. # # The contents of this file are subject to the terms of the # Common Development and Distribution License, Version 1.0 only # (the "License"). You may not use this file except in compliance # with the License. # # The full text of the License is in LICENSE.txt. See the License # for the specific language governing permissions and limitations # under the License. # # When distributing Covered Software, include this CDDL HEADER in # each file and include LICENSE.txt. If applicable, add the # following below this CDDL HEADER, with the fields enclosed by # brackets "[]" replaced with your own identifying information: # Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END from flarelint import rule from flarelint import flarenode rule.Error( extensions=rule.TOPICS, match=flarenode.whenself('body'), test=lambda n: n.child('h1'), message="""Missing title (`h1`). To fix, add a title to the beginning of the topic body.""")
# under the License. # # When distributing Covered Software, include this CDDL HEADER in # each file and include LICENSE.txt. If applicable, add the # following below this CDDL HEADER, with the fields enclosed by # brackets "[]" replaced with your own identifying information: # Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END from flarelint import rule from flarelint import flarenode rule.Error( extensions = rule.TOPICS_AND_SNIPPETS, # This match function is also the test. We do this to make sure # that the message generated from the failure of the test refers # to the offending non-li element. match = lambda n: n.iselement('*', lambda n: (n.parent('ol') or n.parent('ul')) and n.name() != 'li'), test = lambda n: False, message = """A non-list element in a list. Only `li` elements are supported in lists. To fix, convert this element to a list item or wrap it in a list item.""" )
# # Copyright 2016-2017 Intelerad Medical Systems Incorporated. All # rights reserved. # # The contents of this file are subject to the terms of the # Common Development and Distribution License, Version 1.0 only # (the "License"). You may not use this file except in compliance # with the License. # # The full text of the License is in LICENSE.txt. See the License # for the specific language governing permissions and limitations # under the License. # # When distributing Covered Software, include this CDDL HEADER in # each file and include LICENSE.txt. If applicable, add the # following below this CDDL HEADER, with the fields enclosed by # brackets "[]" replaced with your own identifying information: # Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END from flarelint import rule from flarelint import flarenode rule.Error( extensions=rule.TOPICS_AND_SNIPPETS, match=flarenode.whenself('table'), test=lambda n: 'mc-table-style' in n.attribute('style'), message="""Missing style for a table. What kind of table is this? To fix, right-click the table, choose a style from Table Style.""")
# # The contents of this file are subject to the terms of the # Common Development and Distribution License, Version 1.0 only # (the "License"). You may not use this file except in compliance # with the License. # # The full text of the License is in LICENSE.txt. See the License # for the specific language governing permissions and limitations # under the License. # # When distributing Covered Software, include this CDDL HEADER in # each file and include LICENSE.txt. If applicable, add the # following below this CDDL HEADER, with the fields enclosed by # brackets "[]" replaced with your own identifying information: # Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END from flarelint import rule from flarelint import flarenode rule.Error( extensions=rule.TOPICS_AND_SNIPPETS, match=flarenode.whenself('div'), test=lambda n: n.attribute('style') == '', message="""Text box with hard-coded style formatting. This style formatting could include width, height, or border. This formatting is handled by our stylesheets. To fix, set the formatting for border, width, height, and so on, to (Default) in the Text Box Properties dialog. """)