InteractiveHtmlBom 2.11.2__tar.gz → 2.12.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/.gitignore +7 -0
  2. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/core/config.py +147 -0
  3. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/ecad/kicad.py +37 -0
  4. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/generate_interactive_bom.py +21 -4
  5. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/version.py +1 -1
  6. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/web/ibom.css +1 -1
  7. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/web/render.js +3 -3
  8. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/PKG-INFO +2 -2
  9. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/.github/workflows/ci.yml +0 -0
  10. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/.github/workflows/release.yml +0 -0
  11. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/.jsbeautifyrc +0 -0
  12. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/DATAFORMAT.md +0 -0
  13. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/.gitattributes +0 -0
  14. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/Run.bat +0 -0
  15. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/__init__.py +0 -0
  16. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/compat.py +0 -0
  17. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/core/__init__.py +0 -0
  18. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/core/fontparser.py +0 -0
  19. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/core/ibom.py +0 -0
  20. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/core/lzstring.py +0 -0
  21. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/core/newstroke_font.py +0 -0
  22. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/core/units.py +0 -0
  23. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/dialog/__init__.py +0 -0
  24. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/dialog/bitmaps/btn-arrow-down.png +0 -0
  25. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/dialog/bitmaps/btn-arrow-up.png +0 -0
  26. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/dialog/bitmaps/btn-minus.png +0 -0
  27. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/dialog/bitmaps/btn-plus.png +0 -0
  28. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/dialog/bitmaps/btn-question.png +0 -0
  29. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/dialog/dialog_base.py +0 -0
  30. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/dialog/settings_dialog.py +0 -0
  31. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/dialog_test.py +0 -0
  32. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/ecad/__init__.py +0 -0
  33. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/ecad/common.py +0 -0
  34. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/ecad/easyeda.py +0 -0
  35. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/ecad/fusion_eagle.py +0 -0
  36. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/ecad/genericjson.py +0 -0
  37. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/ecad/kicad_extra/__init__.py +0 -0
  38. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/ecad/kicad_extra/netlistparser.py +0 -0
  39. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/ecad/kicad_extra/parser_base.py +0 -0
  40. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/ecad/kicad_extra/sexpressions.py +0 -0
  41. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/ecad/kicad_extra/xmlparser.py +0 -0
  42. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/ecad/schema/genericjsonpcbdata_v1.schema +0 -0
  43. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/ecad/svgpath.py +0 -0
  44. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/errors.py +0 -0
  45. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/i18n/language_en.bat +0 -0
  46. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/i18n/language_zh.bat +0 -0
  47. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/icon.png +0 -0
  48. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/web/ibom.html +0 -0
  49. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/web/ibom.js +0 -0
  50. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/web/lz-string.js +0 -0
  51. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/web/pep.js +0 -0
  52. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/web/split.js +0 -0
  53. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/web/table-util.js +0 -0
  54. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/InteractiveHtmlBom/web/util.js +0 -0
  55. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/LICENSE +0 -0
  56. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/README.md +0 -0
  57. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/__init__.py +0 -0
  58. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/icons/baseline-settings-20px.svg +0 -0
  59. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/icons/bom-grouped-32px.svg +0 -0
  60. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/icons/bom-left-right-32px.svg +0 -0
  61. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/icons/bom-netlist-32px.svg +0 -0
  62. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/icons/bom-only-32px.svg +0 -0
  63. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/icons/bom-top-bot-32px.svg +0 -0
  64. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/icons/bom-ungrouped-32px.svg +0 -0
  65. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/icons/btn-arrow-down.svg +0 -0
  66. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/icons/btn-arrow-up.svg +0 -0
  67. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/icons/btn-minus.svg +0 -0
  68. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/icons/btn-plus.svg +0 -0
  69. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/icons/btn-question.svg +0 -0
  70. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/icons/copy-48px.svg +0 -0
  71. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/icons/io-36px.svg +0 -0
  72. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/icons/plugin.svg +0 -0
  73. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/icons/plugin_icon_big.png +0 -0
  74. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/icons/stats-36px.svg +0 -0
  75. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/make_release.py +0 -0
  76. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/pyproject.toml +0 -0
  77. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/settings_dialog.fbp +0 -0
  78. {interactivehtmlbom-2.11.2 → interactivehtmlbom-2.12.0}/tests/test_module.py +0 -0
@@ -9,3 +9,10 @@ demo
9
9
  *config.ini
10
10
  InteractiveHtmlBom/web/user*
11
11
  dist/
12
+
13
+ # kicad's files
14
+ .history
15
+ *.lck
16
+ *.kicad_prl
17
+ *.kicad_pro
18
+ *-backups
@@ -347,15 +347,27 @@ class Config:
347
347
  # Html
348
348
  parser.add_argument('--dark-mode', help='Default to dark mode.',
349
349
  action='store_true')
350
+ parser.add_argument('--no-dark-mode', dest='dark_mode',
351
+ help='Do not default to dark mode.',
352
+ action='store_false', default=False)
350
353
  parser.add_argument('--hide-pads',
351
354
  help='Hide footprint pads by default.',
352
355
  action='store_true')
356
+ parser.add_argument('--show-pads', dest='hide_pads',
357
+ help='Show footprint pads by default.',
358
+ action='store_false', default=False)
353
359
  parser.add_argument('--show-fabrication',
354
360
  help='Show fabrication layer by default.',
355
361
  action='store_true')
362
+ parser.add_argument('--hide-fabrication', dest='show_fabrication',
363
+ help='Hide fabrication layer by default.',
364
+ action='store_false', default=False)
356
365
  parser.add_argument('--hide-silkscreen',
357
366
  help='Hide silkscreen by default.',
358
367
  action='store_true')
368
+ parser.add_argument('--show-silkscreen', dest='hide_silkscreen',
369
+ help='Show silkscreen by default.',
370
+ action='store_false', default=False)
359
371
  parser.add_argument('--highlight-pin1',
360
372
  default=cls.highlight_pin1_choices[0],
361
373
  const=cls.highlight_pin1_choices[1],
@@ -365,6 +377,9 @@ class Config:
365
377
  parser.add_argument('--no-redraw-on-drag',
366
378
  help='Do not redraw pcb on drag by default.',
367
379
  action='store_true')
380
+ parser.add_argument('--redraw-on-drag', dest='no_redraw_on_drag',
381
+ help='Redraw pcb on drag by default.',
382
+ action='store_false', default=False)
368
383
  parser.add_argument('--board-rotation', type=int,
369
384
  default=cls.board_rotation * 5,
370
385
  help='Board rotation in degrees (-180 to 180). '
@@ -372,6 +387,10 @@ class Config:
372
387
  parser.add_argument('--offset-back-rotation',
373
388
  help='Offset the back of the pcb by 180 degrees',
374
389
  action='store_true')
390
+ parser.add_argument('--no-offset-back-rotation',
391
+ dest='offset_back_rotation',
392
+ help='Do not offset the back of the pcb by 180 degrees',
393
+ action='store_false', default=False)
375
394
  parser.add_argument('--checkboxes',
376
395
  default=cls.checkboxes,
377
396
  help='Comma separated list of checkbox columns.')
@@ -388,8 +407,16 @@ class Config:
388
407
  parser.add_argument('--no-compression',
389
408
  help='Disable compression of pcb data.',
390
409
  action='store_true')
410
+ parser.add_argument('--compression', dest='no_compression',
411
+ help='Enable compression of pcb data.',
412
+ action='store_false', default=False)
391
413
  parser.add_argument('--no-browser', help='Do not launch browser.',
392
414
  action='store_true')
415
+ parser.add_argument('--browser', dest='no_browser',
416
+ help='Launch browser.',
417
+ action='store_false', default=False)
418
+ parser.add_argument('--use-ini', help='Use all run options from ibom ini file.',
419
+ action='store_true')
393
420
 
394
421
  # General
395
422
  parser.add_argument('--dest-dir', default=cls.bom_dest_dir,
@@ -400,8 +427,14 @@ class Config:
400
427
  parser.add_argument('--include-tracks', action='store_true',
401
428
  help='Include track/zone information in output. '
402
429
  'F.Cu and B.Cu layers only.')
430
+ parser.add_argument('--exclude-tracks', dest='include_tracks',
431
+ action='store_false', default=False,
432
+ help='Exclude track/zone information from output.')
403
433
  parser.add_argument('--include-nets', action='store_true',
404
434
  help='Include netlist information in output.')
435
+ parser.add_argument('--exclude-nets', dest='include_nets',
436
+ action='store_false', default=False,
437
+ help='Exclude netlist information from output.')
405
438
  parser.add_argument('--sort-order',
406
439
  help='Default sort order for components. '
407
440
  'Must contain "~" once.',
@@ -413,8 +446,15 @@ class Config:
413
446
  'E.g. "X1,MH*"')
414
447
  parser.add_argument('--no-blacklist-virtual', action='store_true',
415
448
  help='Do not blacklist virtual components.')
449
+ parser.add_argument('--blacklist-virtual', dest='no_blacklist_virtual',
450
+ action='store_false', default=False,
451
+ help='Blacklist virtual components.')
416
452
  parser.add_argument('--blacklist-empty-val', action='store_true',
417
453
  help='Blacklist components with empty value.')
454
+ parser.add_argument('--no-blacklist-empty-val',
455
+ dest='blacklist_empty_val',
456
+ action='store_false', default=False,
457
+ help='Do not blacklist components with empty value.')
418
458
 
419
459
  # Fields section
420
460
  parser.add_argument('--netlist-file',
@@ -435,6 +475,10 @@ class Config:
435
475
  help='Normalize extra field name case. E.g. "MPN" '
436
476
  ', "mpn" will be considered the same field.',
437
477
  action='store_true')
478
+ parser.add_argument('--no-normalize-field-case',
479
+ dest='normalize_field_case',
480
+ help='Do not normalize extra field name case.',
481
+ action='store_false', default=False)
438
482
  parser.add_argument('--variant-field',
439
483
  help='Name of the extra field that stores board '
440
484
  'variant for component.')
@@ -451,6 +495,109 @@ class Config:
451
495
  'do not populate status. Components with '
452
496
  'this field not empty will be excluded.')
453
497
 
498
+ def get_ini_defaults(self):
499
+ # type: () -> dict | None
500
+ """Read the ibom ini file and return its values keyed by the dest
501
+ of the matching command line option, suitable for passing to
502
+ ArgumentParser.set_defaults(). Installing the ini values as parser
503
+ defaults makes options given on the command line override the ini
504
+ while all other options fall back to the ini values.
505
+
506
+ Returns None if no ini file exists in the usual locations.
507
+ """
508
+ import configparser
509
+
510
+ if os.path.isfile(self.local_config_file):
511
+ file = self.local_config_file
512
+ elif os.path.isfile(self.global_config_file):
513
+ file = self.global_config_file
514
+ else:
515
+ return None
516
+ print("Loading options from %s" % file)
517
+
518
+ # Interpolation is disabled because values like bom_name_format
519
+ # legitimately contain '%'.
520
+ ini = configparser.ConfigParser(interpolation=None)
521
+ ini.read(file)
522
+
523
+ # Each entry is (section, key, dest, kind) mapping an ini key to
524
+ # the dest of the command line option holding the same setting.
525
+ # kind describes how the ini value translates to the value argparse
526
+ # would have produced for that dest:
527
+ # 'bool': same boolean
528
+ # 'not' : inverted boolean (the ini stores the positive setting,
529
+ # the option's dest stores the negated one)
530
+ # 'str' : verbatim string; comma separated lists stay joined,
531
+ # set_from_args splits them
532
+ # board_rotation is handled separately below. extra_data_file is
533
+ # intentionally not read from the ini; it is chosen dynamically
534
+ # unless given on the command line.
535
+ ini_options = [
536
+ # Html
537
+ ('html_defaults', 'dark_mode', 'dark_mode', 'bool'),
538
+ ('html_defaults', 'show_pads', 'hide_pads', 'not'),
539
+ ('html_defaults', 'show_fabrication', 'show_fabrication',
540
+ 'bool'),
541
+ ('html_defaults', 'show_silkscreen', 'hide_silkscreen', 'not'),
542
+ ('html_defaults', 'highlight_pin1', 'highlight_pin1', 'str'),
543
+ ('html_defaults', 'redraw_on_drag', 'no_redraw_on_drag', 'not'),
544
+ ('html_defaults', 'offset_back_rotation', 'offset_back_rotation',
545
+ 'bool'),
546
+ ('html_defaults', 'checkboxes', 'checkboxes', 'str'),
547
+ ('html_defaults', 'mark_when_checked', 'mark_when_checked',
548
+ 'str'),
549
+ ('html_defaults', 'bom_view', 'bom_view', 'str'),
550
+ ('html_defaults', 'layer_view', 'layer_view', 'str'),
551
+ ('html_defaults', 'compression', 'no_compression', 'not'),
552
+ ('html_defaults', 'open_browser', 'no_browser', 'not'),
553
+ # General
554
+ ('general', 'bom_dest_dir', 'dest_dir', 'str'),
555
+ ('general', 'bom_name_format', 'name_format', 'str'),
556
+ ('general', 'component_sort_order', 'sort_order', 'str'),
557
+ ('general', 'component_blacklist', 'blacklist', 'str'),
558
+ ('general', 'blacklist_virtual', 'no_blacklist_virtual', 'not'),
559
+ ('general', 'blacklist_empty_val', 'blacklist_empty_val',
560
+ 'bool'),
561
+ ('general', 'include_tracks', 'include_tracks', 'bool'),
562
+ ('general', 'include_nets', 'include_nets', 'bool'),
563
+ # Fields
564
+ ('fields', 'show_fields', 'show_fields', 'str'),
565
+ ('fields', 'group_fields', 'group_fields', 'str'),
566
+ ('fields', 'normalize_field_case', 'normalize_field_case',
567
+ 'bool'),
568
+ ('fields', 'board_variant_field', 'variant_field', 'str'),
569
+ ('fields', 'board_variant_whitelist', 'variants_whitelist',
570
+ 'str'),
571
+ ('fields', 'board_variant_blacklist', 'variants_blacklist',
572
+ 'str'),
573
+ ('fields', 'dnp_field', 'dnp_field', 'str'),
574
+ ]
575
+
576
+ defaults = {}
577
+ for section, key, dest, kind in ini_options:
578
+ if not ini.has_option(section, key):
579
+ continue
580
+ if kind == 'bool':
581
+ defaults[dest] = ini.getboolean(section, key)
582
+ elif kind == 'not':
583
+ defaults[dest] = not ini.getboolean(section, key)
584
+ else:
585
+ defaults[dest] = ini.get(section, key)
586
+
587
+ # The ini stores rotation in multiples of 5 degrees, the command
588
+ # line option takes degrees.
589
+ if ini.has_option('html_defaults', 'board_rotation'):
590
+ defaults['board_rotation'] = \
591
+ ini.getint('html_defaults', 'board_rotation') * 5
592
+
593
+ # migration from previous settings
594
+ if defaults.get('highlight_pin1') == '0':
595
+ defaults['highlight_pin1'] = 'none'
596
+ if defaults.get('highlight_pin1') == '1':
597
+ defaults['highlight_pin1'] = 'all'
598
+
599
+ return defaults
600
+
454
601
  def set_from_args(self, args):
455
602
  # type: (argparse.Namespace) -> None
456
603
  import math
@@ -11,6 +11,12 @@ from ..core.config import Config
11
11
  from ..core.fontparser import FontParser
12
12
 
13
13
 
14
+ # sneaky monkeypatch to work around
15
+ # https://gitlab.com/kicad/code/kicad/-/work_items/25423
16
+ if not hasattr(pcbnew.SwigPyIterator, 'next'):
17
+ setattr(pcbnew.SwigPyIterator, 'next', lambda o: next(o))
18
+
19
+
14
20
  KICAD_VERSION = [5, 1, 0]
15
21
 
16
22
  if hasattr(pcbnew, 'Version'):
@@ -263,6 +269,9 @@ class PcbnewParser(EcadParser):
263
269
 
264
270
  for i in range(poly.OutlineCount()):
265
271
  result.append(self.parse_line_chain(poly.Outline(i)))
272
+ if hasattr(poly, "HoleCount"):
273
+ for j in range(poly.HoleCount(i)):
274
+ result.append(self.parse_line_chain(poly.Hole(i, j)))
266
275
 
267
276
  return result
268
277
 
@@ -270,6 +279,17 @@ class PcbnewParser(EcadParser):
270
279
  # type: (pcbnew.PCB_TEXT) -> dict
271
280
  if not d.IsVisible() and d.GetClass() not in ["PTEXT", "PCB_TEXT"]:
272
281
  return None
282
+ if (hasattr(d, "IsKnockout") and d.IsKnockout()
283
+ and hasattr(d, "GetEffectiveShape")):
284
+ shape = d.GetEffectiveShape()
285
+ if (shape and hasattr(shape, "Cast")
286
+ and hasattr(pcbnew, "SH_POLY_SET")
287
+ and shape.Type() == pcbnew.SH_POLY_SET):
288
+ polygons = self.parse_poly_set(shape.Cast())
289
+ if polygons:
290
+ return {
291
+ "polygons": polygons
292
+ }
273
293
  pos = self.normalize(d.GetPosition())
274
294
  if hasattr(d, "GetTextThickness"):
275
295
  thickness = d.GetTextThickness() * 1e-6
@@ -372,6 +392,21 @@ class PcbnewParser(EcadParser):
372
392
  "svgpath": svgpath
373
393
  }
374
394
 
395
+ def parse_barcode(self, d):
396
+ # type: (pcbnew.BOARD_ITEM) -> dict
397
+ if hasattr(d, "GetPolyShape"):
398
+ polygons = self.parse_poly_set(d.GetPolyShape())
399
+ if not polygons:
400
+ return None
401
+ return {
402
+ "type": "polygon",
403
+ "pos": [0, 0],
404
+ "angle": 0,
405
+ "polygons": polygons,
406
+ "filled": 1,
407
+ }
408
+ return None
409
+
375
410
  def parse_drawing(self, d):
376
411
  # type: (pcbnew.BOARD_ITEM) -> list
377
412
  result = []
@@ -387,6 +422,8 @@ class PcbnewParser(EcadParser):
387
422
  s = self.parse_text(d.Text())
388
423
  else:
389
424
  s = self.parse_text(d)
425
+ elif d.GetClass() in ["BARCODE", "PCB_BARCODE"]:
426
+ s = self.parse_barcode(d)
390
427
  else:
391
428
  self.logger.info("Unsupported drawing class %s, skipping",
392
429
  d.GetClass())
@@ -56,16 +56,33 @@ def main():
56
56
  help="KiCad PCB file")
57
57
 
58
58
  Config.add_options(parser, version)
59
- args = parser.parse_args()
60
59
  logger = ibom.Logger(cli=True)
61
60
 
62
- if not os.path.isfile(args.file):
61
+ # First pass over the arguments to find the pcb file and --use-ini.
62
+ pre_args, _ = parser.parse_known_args()
63
+
64
+ if not os.path.isfile(pre_args.file):
63
65
  exit_error(logger, ExitCodes.ERROR_FILE_NOT_FOUND,
64
- "File %s does not exist." % args.file)
66
+ "File %s does not exist." % pre_args.file)
67
+
68
+ config = Config(version,
69
+ os.path.dirname(os.path.abspath(pre_args.file)))
70
+
71
+ # With --use-ini the ini values are installed as parser defaults before
72
+ # the final parse: options given on the command line override the ini
73
+ # while all other options fall back to the ini values.
74
+ if pre_args.use_ini and not pre_args.show_dialog:
75
+ ini_defaults = config.get_ini_defaults()
76
+ if ini_defaults is None:
77
+ exit_error(logger, ExitCodes.ERROR_FILE_NOT_FOUND,
78
+ "No ibom ini file found in usual locations.")
79
+ else:
80
+ parser.set_defaults(**ini_defaults)
81
+
82
+ args = parser.parse_args()
65
83
 
66
84
  print("Loading %s" % args.file)
67
85
 
68
- config = Config(version, os.path.dirname(os.path.abspath(args.file)))
69
86
  config.kicad_variant = args.kicad_variant
70
87
 
71
88
  parser = get_parser_by_extension(
@@ -3,7 +3,7 @@ import os
3
3
  import subprocess
4
4
 
5
5
 
6
- LAST_TAG = 'v2.11.2'
6
+ LAST_TAG = 'v2.12.0'
7
7
 
8
8
 
9
9
  def _get_git_version():
@@ -8,7 +8,7 @@
8
8
  --pin1-outline-color: #ffb629;
9
9
  --pin1-outline-color-highlight: #ffb629;
10
10
  --pin1-outline-color-highlight-both: #fcbb39;
11
- --pin1-outline-color-highlight-marked: #fdbe41;
11
+ --pin1-outline-color-highlight-marked: #00000000;
12
12
  --silkscreen-edge-color: #aa4;
13
13
  --silkscreen-polygon-color: #4aa;
14
14
  --silkscreen-text-color: #4aa;
@@ -347,7 +347,7 @@ function drawFootprint(ctx, layer, scalefactor, footprint, colors, highlight, ou
347
347
  drawDrawing(ctx, scalefactor, drawing.drawing, colors.pad);
348
348
  }
349
349
  }
350
- ctx.lineWidth = 3 / scalefactor;
350
+ ctx.lineWidth = (outline ? 1 : 3) / scalefactor;
351
351
  // draw pads
352
352
  if (settings.renderPads) {
353
353
  for (var pad of footprint.pads) {
@@ -386,7 +386,7 @@ function drawFootprints(canvas, layer, scalefactor, highlight) {
386
386
  }
387
387
 
388
388
  for (var i = 0; i < pcbdata.footprints.length; i++) {
389
- var mod = pcbdata.footprints[i];
389
+ var fp = pcbdata.footprints[i];
390
390
  var outline = settings.renderDnpOutline && pcbdata.bom.skipped.includes(i);
391
391
  var h = highlightedFootprints.includes(i);
392
392
  var d = markedFootprints.has(i);
@@ -403,7 +403,7 @@ function drawFootprints(canvas, layer, scalefactor, highlight) {
403
403
  }
404
404
  }
405
405
  if( h || d || !highlight) {
406
- drawFootprint(ctx, layer, scalefactor, mod, colors, highlight, outline);
406
+ drawFootprint(ctx, layer, scalefactor, fp, colors, highlight, outline);
407
407
  }
408
408
  }
409
409
  }
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: InteractiveHtmlBom
3
- Version: 2.11.2
3
+ Version: 2.12.0
4
4
  Summary: Generate Interactive Html BOM for your electronics projects
5
5
  Project-URL: Documentation, https://github.com/openscopeproject/InteractiveHtmlBom/wiki
6
6
  Project-URL: Issues, https://github.com/openscopeproject/InteractiveHtmlBom/issues