diff --git a/domdiv/__init__.py b/domdiv/__init__.py index 19ce2dd..5a4b9b0 100644 --- a/domdiv/__init__.py +++ b/domdiv/__init__.py @@ -13,6 +13,7 @@ from draw import DividerDrawer LOCATION_CHOICES = ["tab", "body-top", "hide"] NAME_ALIGN_CHOICES = ["left", "right", "centre", "edge"] TAB_SIDE_CHOICES = ["left", "right", "left-alternate", "right-alternate", "full"] +TEXT_CHOICES = ["card", "rules", "blank"] def add_opt(options, option, value): @@ -37,6 +38,21 @@ def parse_opts(argstring): help="'<%f>x<%f>' (size in cm, left/right, top/bottom), default: 1x1") parser.add_option("--papersize", type="string", dest="papersize", default=None, help="'<%f>x<%f>' (size in cm), or 'A4', or 'LETTER'") + parser.add_option("--front", type="choice", choices=TEXT_CHOICES, + dest="text_front", default="card", + help="Text to print on the front of the divider. choices: card, rules, blank;" + " 'card' will print the text from the game card;" + " 'rules' will print additional rules for the game card;" + " 'blank' will not print text on the divider;" + " default:card") + parser.add_option("--back", type="choice", choices=TEXT_CHOICES + ["none"], + dest="text_back", default="rules", + help="Text to print on the back of the divider. choices: card, rules, blank, none;" + " 'card' will print the text from the game card;" + " 'rules' will print additional rules for the game card;" + " 'blank' will not print text on the divider;" + " 'none' will prevent the back pages from printing;" + " default:rules") parser.add_option("--tab_name_align", type="choice", choices=NAME_ALIGN_CHOICES + ["center"], dest="tab_name_align", default="left", help="Alignment of text on the tab. choices: left, right, centre (or center), edge." @@ -104,14 +120,10 @@ def parse_opts(argstring): help="Path to file that enumerates each card to be printed on its own line.") parser.add_option("--no-tab-artwork", action="store_true", dest="no_tab_artwork", help="don't show background artwork on tabs") - parser.add_option("--no-card-rules", action="store_true", dest="no_card_rules", - help="don't print the card's rules on the tab body") parser.add_option("--use-text-set-icon", action="store_true", dest="use_text_set_icon", help="use text/letters to represent a card's set instead of the set icon") parser.add_option("--no-page-footer", action="store_true", dest="no_page_footer", help="don't print the set name at the bottom of the page.") - parser.add_option("--no-card-backs", action="store_true", dest="no_card_backs", - help="don't print the back page of the card sheets.") options, args = parser.parse_args(argstring) if not options.cost: @@ -177,6 +189,7 @@ def parse_cardsize(spec, sleeved): def read_write_card_data(options): data_dir = os.path.join(options.data_path, "card_db", options.language) + add_opt(options, 'data_dir', data_dir) card_db_filepath = os.path.join(data_dir, "cards.json") with codecs.open(card_db_filepath, "r", "utf-8") as cardfile: cards = json.load(cardfile, object_hook=Card.decode_json) @@ -355,6 +368,7 @@ def calculate_layout(options): add_opt(options, 'dividerWidth', dividerWidth) add_opt(options, 'dividerHeight', dividerHeight) + add_opt(options, 'dividerBaseHeight', dividerBaseHeight) add_opt(options, 'dividerWidthReserved', dividerWidth + horizontalBorderSpace) add_opt(options, 'dividerHeightReserved', dividerHeight + verticalBorderSpace) add_opt(options, 'labelWidth', labelWidth) diff --git a/domdiv/draw.py b/domdiv/draw.py index a362439..f49d73f 100644 --- a/domdiv/draw.py +++ b/domdiv/draw.py @@ -50,6 +50,7 @@ class DividerDrawer(object): dividerWidth = options.dividerWidth dividerHeight = options.dividerHeight + dividerBaseHeight = options.dividerBaseHeight tabLabelWidth = options.labelWidth self.tabOutline = [(0, 0, dividerWidth, 0), @@ -58,25 +59,25 @@ class DividerDrawer(object): dividerWidth - tabLabelWidth, dividerHeight), (dividerWidth - tabLabelWidth, dividerHeight, dividerWidth - tabLabelWidth, - dividerHeight), + dividerBaseHeight), (dividerWidth - tabLabelWidth, - dividerHeight, 0, dividerHeight), - (0, dividerHeight, 0, 0)] + dividerBaseHeight, 0, dividerBaseHeight), + (0, dividerBaseHeight, 0, 0)] self.expansionTabOutline = [(0, 0, dividerWidth, 0), (dividerWidth, 0, dividerWidth, - dividerHeight), - (dividerWidth, dividerHeight, - dividerWidth / 2 + tabLabelWidth / 2, dividerHeight), - (dividerWidth / 2 + tabLabelWidth / 2, dividerHeight, + dividerBaseHeight), + (dividerWidth, dividerBaseHeight, + dividerWidth / 2 + tabLabelWidth / 2, dividerBaseHeight), + (dividerWidth / 2 + tabLabelWidth / 2, dividerBaseHeight, dividerWidth / 2 + tabLabelWidth / 2, dividerHeight), (dividerWidth / 2 + tabLabelWidth / 2, dividerHeight, dividerWidth / 2 - tabLabelWidth / 2, dividerHeight), (dividerWidth / 2 - tabLabelWidth / 2, dividerHeight, - dividerWidth / 2 - tabLabelWidth / 2, dividerHeight), - (dividerWidth / 2 - tabLabelWidth / 2, dividerHeight, - 0, dividerHeight), - (0, dividerHeight, 0, 0)] + dividerWidth / 2 - tabLabelWidth / 2, dividerBaseHeight), + (dividerWidth / 2 - tabLabelWidth / 2, dividerBaseHeight, + 0, dividerBaseHeight), + (0, dividerBaseHeight, 0, 0)] self.canvas = canvas.Canvas( fname, pagesize=(options.paperwidth, options.paperheight)) @@ -334,7 +335,7 @@ class DividerDrawer(object): w += drawWordPiece(' ', fontSize) self.canvas.restoreState() - def drawText(self, card, useExtra=False): + def drawText(self, card, divider_text="card"): usedHeight = 0 totalHeight = self.options.dividerHeight - self.options.labelHeight @@ -352,14 +353,23 @@ class DividerDrawer(object): if drewTopIcon: usedHeight += 15 - if self.options.no_card_rules: + # Figure out what text is to be printed on this divider + if divider_text == "blank": + # blank divider, no need to go on return - - # draw text - if useExtra and card.extra: - descriptions = (card.extra,) - else: + elif divider_text == "rules": + # Add the extra rules text to the divider + if card.extra: + descriptions = (card.extra,) + else: + # Asked for rules and they don't exist, so don't print anything + return + elif divider_text == "card": + # Add the card text to the divider descriptions = re.split("\n", card.description) + else: + # Don't know what was asked, so don't print anything + return s = getSampleStyleSheet()['BodyText'] s.fontName = "Times-Roman" @@ -395,15 +405,15 @@ class DividerDrawer(object): p.drawOn(self.canvas, textHorizontalMargin, h) h -= spacerHeight - def drawDivider(self, card, x, y, useExtra=False): + def drawDivider(self, card, x, y, isBack=False, divider_text="card"): # figure out whether the tab should go on the right side or not if self.options.tab_side == "right": - rightSide = useExtra + rightSide = isBack elif self.options.tab_side in ["left", "full"]: - rightSide = not useExtra + rightSide = not isBack else: # alternate the cards - if not useExtra: + if not isBack: rightSide = not self.odd else: rightSide = self.odd @@ -411,7 +421,7 @@ class DividerDrawer(object): # apply the transforms to get us to the corner of the current card self.canvas.resetTransforms() self.canvas.translate(self.options.horizontalMargin, self.options.verticalMargin) - if useExtra: + if isBack: self.canvas.translate(self.options.back_offset, self.options.back_offset_height) self.canvas.translate(x * self.options.dividerWidthReserved, y * self.options.dividerHeightReserved) @@ -419,10 +429,10 @@ class DividerDrawer(object): # actual drawing if not self.options.tabs_only: self.drawOutline( - x, y, rightSide, useExtra, card.getType().getTypeNames() == ('Expansion',)) + x, y, rightSide, isBack, card.getType().getTypeNames() == ('Expansion',)) self.drawTab(card, rightSide) if not self.options.tabs_only: - self.drawText(card, useExtra) + self.drawText(card, divider_text) def drawSetNames(self, pageCards): # print sets for this page @@ -504,14 +514,14 @@ class DividerDrawer(object): x = i % self.options.numDividersHorizontal y = i / self.options.numDividersHorizontal self.canvas.saveState() - self.drawDivider(card, x, self.options.numDividersVertical - 1 - y) + self.drawDivider(card, x, self.options.numDividersVertical - 1 - y, isBack=False, divider_text=self.options.text_front) self.canvas.restoreState() self.odd = not self.odd self.canvas.showPage() if pageNum + 1 == self.options.num_pages: break - if self.options.tabs_only or self.options.no_card_backs: - # no set names or card backs for label-only sheets + if self.options.tabs_only or self.options.text_back == "none": + # Don't print the sheets with the back of the dividers continue if not self.options.no_page_footer and self.options.order != "global": self.drawSetNames(pageCards) @@ -522,8 +532,7 @@ class DividerDrawer(object): x = (self.options.numDividersHorizontal - 1 - i) % self.options.numDividersHorizontal y = i / self.options.numDividersHorizontal self.canvas.saveState() - self.drawDivider( - card, x, self.options.numDividersVertical - 1 - y, useExtra=True) + self.drawDivider(card, x, self.options.numDividersVertical - 1 - y, isBack=True, divider_text=self.options.text_back) self.canvas.restoreState() self.odd = not self.odd self.canvas.showPage() diff --git a/tests/text_tab_tests.py b/tests/text_tab_tests.py new file mode 100644 index 0000000..af5d48c --- /dev/null +++ b/tests/text_tab_tests.py @@ -0,0 +1,260 @@ +import unittest +from .. import domdiv +from reportlab.lib.units import cm + + +class TestTextTabs(unittest.TestCase): + + #################### + # Card Text and Tab Default Test + #################### + def test_text_tabs_default(self): + # should be the default + options, args = domdiv.parse_opts(['commandname']) + self.assertEquals(options.text_front, 'card') + self.assertEquals(options.text_back, 'rules') + self.assertEquals(options.tab_name_align, 'left') + self.assertEquals(options.tab_side, 'right-alternate') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'left') + + #################### + # Card Text Tests + #################### + def test_text_card_rules(self): + options, args = domdiv.parse_opts(['commandname', '--front', 'card', '--back', 'rules') + self.assertEquals(options.text_front, 'card') + self.assertEquals(options.text_back, 'rules') + + def test_text_card_blank(self): + options, args = domdiv.parse_opts(['commandname', '--front', 'card', '--back', 'blank') + self.assertEquals(options.text_front, 'card') + self.assertEquals(options.text_back, 'blank') + + def test_text_card_card(self): + options, args = domdiv.parse_opts(['commandname', '--front', 'card', '--back', 'card') + self.assertEquals(options.text_front, 'card') + self.assertEquals(options.text_back, 'card') + + def test_text_card_none(self): + options, args = domdiv.parse_opts(['commandname', '--front', 'card', '--back', 'none') + self.assertEquals(options.text_front, 'card') + self.assertEquals(options.text_back, 'none') + + def test_text_rules_rules(self): + options, args = domdiv.parse_opts(['commandname', '--front', 'rules', '--back', 'rules') + self.assertEquals(options.text_front, 'rules') + self.assertEquals(options.text_back, 'rules') + + def test_text_rules_blank(self): + options, args = domdiv.parse_opts(['commandname', '--front', 'rules', '--back', 'blank') + self.assertEquals(options.text_front, 'rules') + self.assertEquals(options.text_back, 'blank') + + def test_text_rules_card(self): + options, args = domdiv.parse_opts(['commandname', '--front', 'rules', '--back', 'card') + self.assertEquals(options.text_front, 'rules') + self.assertEquals(options.text_back, 'card') + + def test_text_rules_none(self): + options, args = domdiv.parse_opts(['commandname', '--front', 'rules', '--back', 'none') + self.assertEquals(options.text_front, 'rules') + self.assertEquals(options.text_back, 'none') + + def test_text_blank_rules(self): + options, args = domdiv.parse_opts(['commandname', '--front', 'blank', '--back', 'rules') + self.assertEquals(options.text_front, 'blank') + self.assertEquals(options.text_back, 'rules') + + def test_text_blank_blank(self): + options, args = domdiv.parse_opts(['commandname', '--front', 'blank', '--back', 'blank') + self.assertEquals(options.text_front, 'blank') + self.assertEquals(options.text_back, 'blank') + + def test_text_blank_card(self): + options, args = domdiv.parse_opts(['commandname', '--front', 'blank', '--back', 'card') + self.assertEquals(options.text_front, 'blank') + self.assertEquals(options.text_back, 'card') + + def test_text_blank_none(self): + options, args = domdiv.parse_opts(['commandname', '--front', 'blank', '--back', 'none') + self.assertEquals(options.text_front, 'blank') + self.assertEquals(options.text_back, 'none') + + #################### + # Card Tab Tests + #################### + # --tab_name_align left + def test_tab_left_left(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'left', '--tab_side', 'left') + self.assertEquals(options.tab_name_align, 'left') + self.assertEquals(options.tab_side, 'left') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'left') + self.assertEquals(options.tab_side, 'left') + + def test_tab_left_right(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'left', '--tab_side', 'right') + self.assertEquals(options.tab_name_align, 'left') + self.assertEquals(options.tab_side, 'right') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'left') + self.assertEquals(options.tab_side, 'right') + + def test_tab_left_leftalt(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'left', '--tab_side', 'left-alternate') + self.assertEquals(options.tab_name_align, 'left') + self.assertEquals(options.tab_side, 'left-alternate') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'left') + self.assertEquals(options.tab_side, 'left-alternate') + + def test_tab_left_rightalt(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'left', '--tab_side', 'right-alternate') + self.assertEquals(options.tab_name_align, 'left') + self.assertEquals(options.tab_side, 'right-alternate') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'left') + self.assertEquals(options.tab_side, 'right-alternate') + + def test_tab_left_full(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'left', '--tab_side', 'full') + self.assertEquals(options.tab_name_align, 'left') + self.assertEquals(options.tab_side, 'full') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'left') + self.assertEquals(options.tab_side, 'full') + + # --tab_name_align right + def test_tab_right_left(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'right', '--tab_side', 'left') + self.assertEquals(options.tab_name_align, 'right') + self.assertEquals(options.tab_side, 'left') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'right') + self.assertEquals(options.tab_side, 'left') + + def test_tab_right_right(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'right', '--tab_side', 'right') + self.assertEquals(options.tab_name_align, 'right') + self.assertEquals(options.tab_side, 'right') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'right') + self.assertEquals(options.tab_side, 'right') + + def test_tab_right_leftalt(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'right', '--tab_side', 'left-alternate') + self.assertEquals(options.tab_name_align, 'right') + self.assertEquals(options.tab_side, 'left-alternate') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'right') + self.assertEquals(options.tab_side, 'left-alternate') + + def test_tab_right_rightalt(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'right', '--tab_side', 'right-alternate') + self.assertEquals(options.tab_name_align, 'right') + self.assertEquals(options.tab_side, 'right-alternate') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'right') + self.assertEquals(options.tab_side, 'right-alternate') + + def test_tab_right_full(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'right', '--tab_side', 'full') + self.assertEquals(options.tab_name_align, 'right') + self.assertEquals(options.tab_side, 'full') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'right') + self.assertEquals(options.tab_side, 'full') + + # --tab_name_align edge + def test_tab_edge_left(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'edge', '--tab_side', 'left') + self.assertEquals(options.tab_name_align, 'edge') + self.assertEquals(options.tab_side, 'left') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'edge') + self.assertEquals(options.tab_side, 'left') + + def test_tab_edge_right(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'edge', '--tab_side', 'right') + self.assertEquals(options.tab_name_align, 'edge') + self.assertEquals(options.tab_side, 'right') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'edge') + self.assertEquals(options.tab_side, 'right') + + def test_tab_edge_leftalt(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'edge', '--tab_side', 'left-alternate') + self.assertEquals(options.tab_name_align, 'edge') + self.assertEquals(options.tab_side, 'left-alternate') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'edge') + self.assertEquals(options.tab_side, 'left-alternate') + + def test_tab_edge_rightalt(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'edge', '--tab_side', 'right-alternate') + self.assertEquals(options.tab_name_align, 'edge') + self.assertEquals(options.tab_side, 'right-alternate') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'edge') + self.assertEquals(options.tab_side, 'right-alternate') + + def test_tab_edge_full(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'edge', '--tab_side', 'full') + self.assertEquals(options.tab_name_align, 'edge') + self.assertEquals(options.tab_side, 'full') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'left') # special check for odd condition + self.assertEquals(options.tab_side, 'full') + + # --tab_name_align centre + def test_tab_centre_left(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'centre', '--tab_side', 'left') + self.assertEquals(options.tab_name_align, 'centre') + self.assertEquals(options.tab_side, 'left') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'centre') + self.assertEquals(options.tab_side, 'left') + + def test_tab_centre_right(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'centre', '--tab_side', 'right') + self.assertEquals(options.tab_name_align, 'centre') + self.assertEquals(options.tab_side, 'right') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'centre') + self.assertEquals(options.tab_side, 'right') + + def test_tab_centre_leftalt(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'centre', '--tab_side', 'left-alternate') + self.assertEquals(options.tab_name_align, 'centre') + self.assertEquals(options.tab_side, 'left-alternate') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'centre') + self.assertEquals(options.tab_side, 'left-alternate') + + def test_tab_centre_rightalt(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'centre', '--tab_side', 'right-alternate') + self.assertEquals(options.tab_name_align, 'centre') + self.assertEquals(options.tab_side, 'right-alternate') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'centre') + self.assertEquals(options.tab_side, 'right-alternate') + + def test_tab_centre_full(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'centre', '--tab_side', 'full') + self.assertEquals(options.tab_name_align, 'centre') + self.assertEquals(options.tab_side, 'full') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'centre') + self.assertEquals(options.tab_side, 'full') + + # --tab_name_align center. Just do one since this is an alias to centre + def test_tab_center_left(self): + options, args = domdiv.parse_opts(['commandname', '--tab_name_align', 'center', '--tab_side', 'left') + self.assertEquals(options.tab_name_align, 'center') + self.assertEquals(options.tab_side, 'left') + domdiv.calculate_layout(options) + self.assertEquals(options.tab_name_align, 'centre') # check for change in value + self.assertEquals(options.tab_side, 'left') + +