PCB PDF Print: mechanism to change the block title.
- Related to #102 - Also added %V to expand the variant name - Documented %v and %V
This commit is contained in:
parent
cfcc9bea39
commit
b4c1531e10
|
|
@ -23,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- Generic filter: options to match if a field is/isn't defined.
|
- Generic filter: options to match if a field is/isn't defined.
|
||||||
- Excellon drill: added `route_mode_for_oval_holes` option.
|
- Excellon drill: added `route_mode_for_oval_holes` option.
|
||||||
- Default global `dir` option.
|
- Default global `dir` option.
|
||||||
|
- Pattern to expand the variant name: %V
|
||||||
|
- PCB PDF Print: mechanism to change the block title. (#102)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Internal BoM: now components with different Tolerance, Voltage, Current
|
- Internal BoM: now components with different Tolerance, Voltage, Current
|
||||||
|
|
|
||||||
14
README.md
14
README.md
|
|
@ -198,16 +198,18 @@ You can always choose the file name for a particular output.
|
||||||
|
|
||||||
The pattern uses the following expansions:
|
The pattern uses the following expansions:
|
||||||
|
|
||||||
- **%f** original pcb/sch file name without extension.
|
|
||||||
- **%F** original pcb/sch file name without extension. Including the directory part of the name.
|
|
||||||
- **%p** pcb/sch title from pcb metadata.
|
|
||||||
- **%c** company from pcb/sch metadata.
|
- **%c** company from pcb/sch metadata.
|
||||||
- **%r** revision from pcb/sch metadata.
|
|
||||||
- **%d** pcb/sch date from metadata if available, file modification date otherwise.
|
- **%d** pcb/sch date from metadata if available, file modification date otherwise.
|
||||||
- **%D** date the script was started.
|
- **%D** date the script was started.
|
||||||
- **%T** time the script was started.
|
- **%f** original pcb/sch file name without extension.
|
||||||
|
- **%F** original pcb/sch file name without extension. Including the directory part of the name.
|
||||||
- **%i** a contextual ID, depends on the output type.
|
- **%i** a contextual ID, depends on the output type.
|
||||||
|
- **%p** pcb/sch title from pcb metadata.
|
||||||
|
- **%r** revision from pcb/sch metadata.
|
||||||
|
- **%T** time the script was started.
|
||||||
- **%x** a suitable extension for the output type.
|
- **%x** a suitable extension for the output type.
|
||||||
|
- **%v** the `file_id` of the current variant.
|
||||||
|
- **%V** the `name` of the current variant.
|
||||||
|
|
||||||
They are compatible with the ones used by IBoM.
|
They are compatible with the ones used by IBoM.
|
||||||
The default value for `global.output` is `%f-%i.%x`.
|
The default value for `global.output` is `%f-%i.%x`.
|
||||||
|
|
@ -1299,6 +1301,8 @@ Next time you need this list just use an alias, like this:
|
||||||
- `plot_sheet_reference`: [boolean=true] Include the title-block.
|
- `plot_sheet_reference`: [boolean=true] Include the title-block.
|
||||||
- `scaling`: [number=1.0] Scale factor (0 means autoscaling).
|
- `scaling`: [number=1.0] Scale factor (0 means autoscaling).
|
||||||
- `separated`: [boolean=false] Print layers in separated pages.
|
- `separated`: [boolean=false] Print layers in separated pages.
|
||||||
|
- `title`: [string=''] Text used to replace the sheet title. %VALUE expansions are allowed.
|
||||||
|
If it starts with `+` the text is concatenated.
|
||||||
- `variant`: [string=''] Board variant to apply.
|
- `variant`: [string=''] Board variant to apply.
|
||||||
|
|
||||||
* PDF Schematic Print (Portable Document Format)
|
* PDF Schematic Print (Portable Document Format)
|
||||||
|
|
|
||||||
|
|
@ -177,16 +177,18 @@ You can always choose the file name for a particular output.
|
||||||
|
|
||||||
The pattern uses the following expansions:
|
The pattern uses the following expansions:
|
||||||
|
|
||||||
- **%f** original pcb/sch file name without extension.
|
|
||||||
- **%F** original pcb/sch file name without extension. Including the directory part of the name.
|
|
||||||
- **%p** pcb/sch title from pcb metadata.
|
|
||||||
- **%c** company from pcb/sch metadata.
|
- **%c** company from pcb/sch metadata.
|
||||||
- **%r** revision from pcb/sch metadata.
|
|
||||||
- **%d** pcb/sch date from metadata if available, file modification date otherwise.
|
- **%d** pcb/sch date from metadata if available, file modification date otherwise.
|
||||||
- **%D** date the script was started.
|
- **%D** date the script was started.
|
||||||
- **%T** time the script was started.
|
- **%f** original pcb/sch file name without extension.
|
||||||
|
- **%F** original pcb/sch file name without extension. Including the directory part of the name.
|
||||||
- **%i** a contextual ID, depends on the output type.
|
- **%i** a contextual ID, depends on the output type.
|
||||||
|
- **%p** pcb/sch title from pcb metadata.
|
||||||
|
- **%r** revision from pcb/sch metadata.
|
||||||
|
- **%T** time the script was started.
|
||||||
- **%x** a suitable extension for the output type.
|
- **%x** a suitable extension for the output type.
|
||||||
|
- **%v** the `file_id` of the current variant.
|
||||||
|
- **%V** the `name` of the current variant.
|
||||||
|
|
||||||
They are compatible with the ones used by IBoM.
|
They are compatible with the ones used by IBoM.
|
||||||
The default value for `global.output` is `%f-%i.%x`.
|
The default value for `global.output` is `%f-%i.%x`.
|
||||||
|
|
|
||||||
|
|
@ -898,6 +898,9 @@ outputs:
|
||||||
scaling: 1.0
|
scaling: 1.0
|
||||||
# [boolean=false] Print layers in separated pages
|
# [boolean=false] Print layers in separated pages
|
||||||
separated: false
|
separated: false
|
||||||
|
# [string=''] Text used to replace the sheet title. %VALUE expansions are allowed.
|
||||||
|
# If it starts with `+` the text is concatenated
|
||||||
|
title: ''
|
||||||
# [string=''] Board variant to apply
|
# [string=''] Board variant to apply
|
||||||
variant: ''
|
variant: ''
|
||||||
layers: all
|
layers: all
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,13 @@ class Optionable(object):
|
||||||
return self.variant.file_id
|
return self.variant.file_id
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
def _find_variant_name(self):
|
||||||
|
""" Returns the name for the current variant.
|
||||||
|
If no variant is defined an empty string is returned. """
|
||||||
|
if hasattr(self, 'variant') and self.variant and hasattr(self.variant, 'name'):
|
||||||
|
return self.variant.name
|
||||||
|
return ''
|
||||||
|
|
||||||
def expand_filename_pcb(self, name):
|
def expand_filename_pcb(self, name):
|
||||||
""" Expands %* values in filenames.
|
""" Expands %* values in filenames.
|
||||||
Uses data from the PCB. """
|
Uses data from the PCB. """
|
||||||
|
|
@ -210,6 +217,7 @@ class Optionable(object):
|
||||||
name = name.replace('%r', GS.pcb_rev)
|
name = name.replace('%r', GS.pcb_rev)
|
||||||
name = name.replace('%T', GS.time)
|
name = name.replace('%T', GS.time)
|
||||||
name = name.replace('%v', self._find_variant() if self else '')
|
name = name.replace('%v', self._find_variant() if self else '')
|
||||||
|
name = name.replace('%V', self._find_variant_name() if self else '')
|
||||||
name = name.replace('%x', self._expand_ext)
|
name = name.replace('%x', self._expand_ext)
|
||||||
# sanitize the name to avoid characters illegal in file systems
|
# sanitize the name to avoid characters illegal in file systems
|
||||||
name = name.replace('\\', '/')
|
name = name.replace('\\', '/')
|
||||||
|
|
@ -232,6 +240,7 @@ class Optionable(object):
|
||||||
name = name.replace('%r', GS.sch_rev)
|
name = name.replace('%r', GS.sch_rev)
|
||||||
name = name.replace('%T', GS.time)
|
name = name.replace('%T', GS.time)
|
||||||
name = name.replace('%v', self._find_variant() if self else '')
|
name = name.replace('%v', self._find_variant() if self else '')
|
||||||
|
name = name.replace('%V', self._find_variant_name() if self else '')
|
||||||
name = name.replace('%x', self._expand_ext)
|
name = name.replace('%x', self._expand_ext)
|
||||||
# sanitize the name to avoid characters illegal in file systems
|
# sanitize the name to avoid characters illegal in file systems
|
||||||
name = name.replace('\\', '/')
|
name = name.replace('\\', '/')
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,8 @@ class VariantOptions(BaseOptions):
|
||||||
|
|
||||||
def cross_modules(self, board, comps_hash):
|
def cross_modules(self, board, comps_hash):
|
||||||
""" Draw a cross in all 'not fitted' modules using *.Fab layer """
|
""" Draw a cross in all 'not fitted' modules using *.Fab layer """
|
||||||
|
if comps_hash is None:
|
||||||
|
return
|
||||||
# Cross the affected components
|
# Cross the affected components
|
||||||
ffab = board.GetLayerID('F.Fab')
|
ffab = board.GetLayerID('F.Fab')
|
||||||
bfab = board.GetLayerID('B.Fab')
|
bfab = board.GetLayerID('B.Fab')
|
||||||
|
|
@ -214,6 +216,8 @@ class VariantOptions(BaseOptions):
|
||||||
|
|
||||||
def uncross_modules(self, board, comps_hash):
|
def uncross_modules(self, board, comps_hash):
|
||||||
""" Undo the crosses in *.Fab layer """
|
""" Undo the crosses in *.Fab layer """
|
||||||
|
if comps_hash is None:
|
||||||
|
return
|
||||||
# Undo the drawings
|
# Undo the drawings
|
||||||
for m in board.GetModules():
|
for m in board.GetModules():
|
||||||
ref = m.GetReference()
|
ref = m.GetReference()
|
||||||
|
|
@ -230,6 +234,8 @@ class VariantOptions(BaseOptions):
|
||||||
|
|
||||||
def remove_paste_and_glue(self, board, comps_hash):
|
def remove_paste_and_glue(self, board, comps_hash):
|
||||||
""" Remove from solder paste layers the filtered components. """
|
""" Remove from solder paste layers the filtered components. """
|
||||||
|
if comps_hash is None:
|
||||||
|
return
|
||||||
exclude = LSET()
|
exclude = LSET()
|
||||||
fpaste = board.GetLayerID('F.Paste')
|
fpaste = board.GetLayerID('F.Paste')
|
||||||
bpaste = board.GetLayerID('B.Paste')
|
bpaste = board.GetLayerID('B.Paste')
|
||||||
|
|
@ -279,6 +285,8 @@ class VariantOptions(BaseOptions):
|
||||||
return exclude
|
return exclude
|
||||||
|
|
||||||
def restore_paste_and_glue(self, board, comps_hash):
|
def restore_paste_and_glue(self, board, comps_hash):
|
||||||
|
if comps_hash is None:
|
||||||
|
return
|
||||||
for m in board.GetModules():
|
for m in board.GetModules():
|
||||||
ref = m.GetReference()
|
ref = m.GetReference()
|
||||||
c = comps_hash.get(ref, None)
|
c = comps_hash.get(ref, None)
|
||||||
|
|
@ -296,6 +304,8 @@ class VariantOptions(BaseOptions):
|
||||||
|
|
||||||
def remove_fab(self, board, comps_hash):
|
def remove_fab(self, board, comps_hash):
|
||||||
""" Remove from Fab the excluded components. """
|
""" Remove from Fab the excluded components. """
|
||||||
|
if comps_hash is None:
|
||||||
|
return
|
||||||
ffab = board.GetLayerID('F.Fab')
|
ffab = board.GetLayerID('F.Fab')
|
||||||
bfab = board.GetLayerID('B.Fab')
|
bfab = board.GetLayerID('B.Fab')
|
||||||
old_ffab = []
|
old_ffab = []
|
||||||
|
|
@ -321,11 +331,28 @@ class VariantOptions(BaseOptions):
|
||||||
self.bfab = bfab
|
self.bfab = bfab
|
||||||
|
|
||||||
def restore_fab(self, board, comps_hash):
|
def restore_fab(self, board, comps_hash):
|
||||||
|
if comps_hash is None:
|
||||||
|
return
|
||||||
for gi in self.old_ffab:
|
for gi in self.old_ffab:
|
||||||
gi.SetLayer(self.ffab)
|
gi.SetLayer(self.ffab)
|
||||||
for gi in self.old_bfab:
|
for gi in self.old_bfab:
|
||||||
gi.SetLayer(self.bfab)
|
gi.SetLayer(self.bfab)
|
||||||
|
|
||||||
|
def set_title(self, title):
|
||||||
|
self.old_title = None
|
||||||
|
if title:
|
||||||
|
tb = GS.board.GetTitleBlock()
|
||||||
|
self.old_title = tb.GetTitle()
|
||||||
|
text = self.expand_filename_pcb(title)
|
||||||
|
if text[0] == '+':
|
||||||
|
text = self.old_title+text[1:]
|
||||||
|
tb.SetTitle(text)
|
||||||
|
|
||||||
|
def restore_title(self):
|
||||||
|
self.old_title = None
|
||||||
|
if self.old_title is not None:
|
||||||
|
GS.board.GetTitleBlock().SetTitle(self.old_title)
|
||||||
|
|
||||||
def run(self, output_dir):
|
def run(self, output_dir):
|
||||||
""" Makes the list of components available """
|
""" Makes the list of components available """
|
||||||
if not self.dnf_filter and not self.variant:
|
if not self.dnf_filter and not self.variant:
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,9 @@ class PDF_Pcb_PrintOptions(VariantOptions):
|
||||||
""" Print mirrored (X axis inverted). ONLY for KiCad 6 """
|
""" Print mirrored (X axis inverted). ONLY for KiCad 6 """
|
||||||
self.hide_excluded = False
|
self.hide_excluded = False
|
||||||
""" Hide components in the Fab layer that are marked as excluded by a variant """
|
""" Hide components in the Fab layer that are marked as excluded by a variant """
|
||||||
|
self.title = ''
|
||||||
|
""" Text used to replace the sheet title. %VALUE expansions are allowed.
|
||||||
|
If it starts with `+` the text is concatenated """
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._expand_ext = 'pdf'
|
self._expand_ext = 'pdf'
|
||||||
|
|
||||||
|
|
@ -71,8 +74,8 @@ class PDF_Pcb_PrintOptions(VariantOptions):
|
||||||
copy2(pro_name, pro_copy)
|
copy2(pro_name, pro_copy)
|
||||||
return pro_copy
|
return pro_copy
|
||||||
|
|
||||||
def filter_components(self, board):
|
def filter_components(self, board, force_copy):
|
||||||
if not self._comps:
|
if not self._comps and not force_copy:
|
||||||
return GS.pcb_file, None
|
return GS.pcb_file, None
|
||||||
comps_hash = self.get_refs_hash()
|
comps_hash = self.get_refs_hash()
|
||||||
self.cross_modules(board, comps_hash)
|
self.cross_modules(board, comps_hash)
|
||||||
|
|
@ -85,7 +88,7 @@ class PDF_Pcb_PrintOptions(VariantOptions):
|
||||||
logger.debug('Storing filtered PCB to `{}`'.format(fname))
|
logger.debug('Storing filtered PCB to `{}`'.format(fname))
|
||||||
GS.board.Save(fname)
|
GS.board.Save(fname)
|
||||||
# Copy the project: avoids warnings, could carry some options
|
# Copy the project: avoids warnings, could carry some options
|
||||||
fproj = self._copy_project(fname)
|
self._copy_project(fname)
|
||||||
self.uncross_modules(board, comps_hash)
|
self.uncross_modules(board, comps_hash)
|
||||||
self.restore_paste_and_glue(board, comps_hash)
|
self.restore_paste_and_glue(board, comps_hash)
|
||||||
if self.hide_excluded:
|
if self.hide_excluded:
|
||||||
|
|
@ -111,13 +114,15 @@ class PDF_Pcb_PrintOptions(VariantOptions):
|
||||||
cmd.append('--separate')
|
cmd.append('--separate')
|
||||||
if self.mirror:
|
if self.mirror:
|
||||||
cmd.append('--mirror')
|
cmd.append('--mirror')
|
||||||
board_name, board_dir = self.filter_components(GS.board)
|
self.set_title(self.title)
|
||||||
|
board_name, board_dir = self.filter_components(GS.board, self.title != '')
|
||||||
cmd.extend([board_name, os.path.dirname(output)])
|
cmd.extend([board_name, os.path.dirname(output)])
|
||||||
cmd, video_remove = add_extra_options(cmd)
|
cmd, video_remove = add_extra_options(cmd)
|
||||||
# Add the layers
|
# Add the layers
|
||||||
cmd.extend([la.layer for la in self._layers])
|
cmd.extend([la.layer for la in self._layers])
|
||||||
# Execute it
|
# Execute it
|
||||||
ret = exec_with_retry(cmd)
|
ret = exec_with_retry(cmd)
|
||||||
|
self.restore_title()
|
||||||
# Remove the temporal PCB
|
# Remove the temporal PCB
|
||||||
if board_dir:
|
if board_dir:
|
||||||
logger.debug('Removing temporal variant dir `{}`'.format(board_dir))
|
logger.debug('Removing temporal variant dir `{}`'.format(board_dir))
|
||||||
|
|
|
||||||
|
|
@ -107,3 +107,6 @@ class BasePreFlight(Registrable):
|
||||||
|
|
||||||
def _find_variant(self):
|
def _find_variant(self):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
def _find_variant_name(self):
|
||||||
|
return ''
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ class BaseVariant(RegVariant):
|
||||||
self.comment = ''
|
self.comment = ''
|
||||||
""" A comment for documentation purposes """
|
""" A comment for documentation purposes """
|
||||||
self.file_id = ''
|
self.file_id = ''
|
||||||
""" Text to use as the """
|
""" Text to use as the replacement for %v expansion """
|
||||||
# * Filters
|
# * Filters
|
||||||
self.pre_transform = Optionable
|
self.pre_transform = Optionable
|
||||||
""" [string|list(string)=''] Name of the filter to transform fields before applying other filters.
|
""" [string|list(string)=''] Name of the filter to transform fields before applying other filters.
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ outputs:
|
||||||
comment: "Print F.Cu+F.SilkS"
|
comment: "Print F.Cu+F.SilkS"
|
||||||
type: pdf_pcb_print
|
type: pdf_pcb_print
|
||||||
dir: Layers
|
dir: Layers
|
||||||
|
options:
|
||||||
|
title: 'Fake title for front copper and silk'
|
||||||
layers:
|
layers:
|
||||||
- layer: F.Cu
|
- layer: F.Cu
|
||||||
- layer: F.SilkS
|
- layer: F.SilkS
|
||||||
|
|
|
||||||
|
|
@ -15,4 +15,5 @@ outputs:
|
||||||
options:
|
options:
|
||||||
variant: default
|
variant: default
|
||||||
scaling: 0
|
scaling: 0
|
||||||
|
title: 'Hello %V'
|
||||||
layers: F.Fab
|
layers: F.Fab
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue