sysmlpy 0.33.2__tar.gz → 0.33.4__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 (147) hide show
  1. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/PKG-INFO +14 -1
  2. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/README.md +13 -0
  3. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/pyproject.toml +1 -1
  4. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/__init__.py +4 -2
  5. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/antlr_visitor.py +154 -0
  6. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/grammar/classes.py +36 -0
  7. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/plantuml.py +341 -38
  8. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/usage.py +8 -0
  9. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/LICENSE +0 -0
  10. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/__main__.py +0 -0
  11. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/antlr/README.md +0 -0
  12. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/antlr/SysMLv2Lexer.interp +0 -0
  13. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/antlr/SysMLv2Lexer.py +0 -0
  14. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/antlr/SysMLv2Lexer.tokens +0 -0
  15. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/antlr/SysMLv2Parser.interp +0 -0
  16. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/antlr/SysMLv2Parser.py +0 -0
  17. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/antlr/SysMLv2Parser.tokens +0 -0
  18. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/antlr/SysMLv2ParserListener.py +0 -0
  19. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/antlr/SysMLv2ParserVisitor.py +0 -0
  20. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  21. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  22. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  23. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/antlr_parser.py +0 -0
  24. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/definition.py +0 -0
  25. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/examples/attribute_values.py +0 -0
  26. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/examples/part_attributes.py +0 -0
  27. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/examples/tuples_sequences.py +0 -0
  28. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/formatting.py +0 -0
  29. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/grammar/antlr4/README.md +0 -0
  30. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.g4 +0 -0
  31. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  32. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  33. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  34. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.g4 +0 -0
  35. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.interp +0 -0
  36. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.py +0 -0
  37. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.tokens +0 -0
  38. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/grammar/antlr4/SysMLv2ParserListener.py +0 -0
  39. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/grammar/antlr4/SysMLv2ParserVisitor.py +0 -0
  40. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/grammar/antlr4/desc.xml +0 -0
  41. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/grammar/antlr4/examples/camera.sysml +0 -0
  42. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/grammar/antlr4/examples/toaster-system.sysml +0 -0
  43. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/grammar/antlr4/examples/vehicle-model.sysml +0 -0
  44. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/grammar/antlr4/pom.xml +0 -0
  45. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/LICENSE +0 -0
  46. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/README.md +0 -0
  47. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/__init__.py +0 -0
  48. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Analysis/AnalysisTooling.sysml +0 -0
  49. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Analysis/SampledFunctions.sysml +0 -0
  50. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Analysis/StateSpaceRepresentation.sysml +0 -0
  51. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Analysis/TradeStudies.sysml +0 -0
  52. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Cause and Effect/CausationConnections.sysml +0 -0
  53. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Cause and Effect/CauseAndEffect.sysml +0 -0
  54. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Geometry/ShapeItems.sysml +0 -0
  55. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Geometry/SpatialItems.sysml +0 -0
  56. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Metadata/ImageMetadata.sysml +0 -0
  57. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Metadata/ModelingMetadata.sysml +0 -0
  58. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Metadata/ParametersOfInterestMetadata.sysml +0 -0
  59. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Metadata/RiskMetadata.sysml +0 -0
  60. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/ISQ.sysml +0 -0
  61. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/ISQAcoustics.sysml +0 -0
  62. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/ISQAtomicNuclear.sysml +0 -0
  63. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/ISQBase.sysml +0 -0
  64. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/ISQCharacteristicNumbers.sysml +0 -0
  65. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/ISQChemistryMolecular.sysml +0 -0
  66. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/ISQCondensedMatter.sysml +0 -0
  67. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/ISQElectromagnetism.sysml +0 -0
  68. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/ISQInformation.sysml +0 -0
  69. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/ISQLight.sysml +0 -0
  70. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/ISQMechanics.sysml +0 -0
  71. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/ISQSpaceTime.sysml +0 -0
  72. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/ISQThermodynamics.sysml +0 -0
  73. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/MeasurementRefCalculations.sysml +0 -0
  74. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/MeasurementReferences.sysml +0 -0
  75. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/Quantities.sysml +0 -0
  76. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/QuantityCalculations.sysml +0 -0
  77. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/SI.sysml +0 -0
  78. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/SIPrefixes.sysml +0 -0
  79. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/TensorCalculations.sysml +0 -0
  80. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/Time.sysml +0 -0
  81. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/USCustomaryUnits.sysml +0 -0
  82. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Quantities and Units/VectorCalculations.sysml +0 -0
  83. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Requirement Derivation/DerivationConnections.sysml +0 -0
  84. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/domain/Requirement Derivation/RequirementDerivation.sysml +0 -0
  85. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/Base.kerml +0 -0
  86. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/BaseFunctions.kerml +0 -0
  87. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/BooleanFunctions.kerml +0 -0
  88. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/Clocks.kerml +0 -0
  89. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/CollectionFunctions.kerml +0 -0
  90. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/Collections.kerml +0 -0
  91. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/ComplexFunctions.kerml +0 -0
  92. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/ControlFunctions.kerml +0 -0
  93. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/ControlPerformances.kerml +0 -0
  94. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/DataFunctions.kerml +0 -0
  95. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/FeatureReferencingPerformances.kerml +0 -0
  96. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/IntegerFunctions.kerml +0 -0
  97. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/KerML.kerml +0 -0
  98. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/Links.kerml +0 -0
  99. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/Metaobjects.kerml +0 -0
  100. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/NaturalFunctions.kerml +0 -0
  101. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/NumericalFunctions.kerml +0 -0
  102. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/Objects.kerml +0 -0
  103. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/Observation.kerml +0 -0
  104. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/OccurrenceFunctions.kerml +0 -0
  105. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/Occurrences.kerml +0 -0
  106. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/Performances.kerml +0 -0
  107. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/RationalFunctions.kerml +0 -0
  108. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/RealFunctions.kerml +0 -0
  109. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/ScalarFunctions.kerml +0 -0
  110. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/ScalarValues.kerml +0 -0
  111. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/SequenceFunctions.kerml +0 -0
  112. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/SpatialFrames.kerml +0 -0
  113. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/StatePerformances.kerml +0 -0
  114. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/StringFunctions.kerml +0 -0
  115. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/Transfers.kerml +0 -0
  116. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/TransitionPerformances.kerml +0 -0
  117. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/TrigFunctions.kerml +0 -0
  118. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/Triggers.kerml +0 -0
  119. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/VectorFunctions.kerml +0 -0
  120. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/kernel/VectorValues.kerml +0 -0
  121. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/Actions.sysml +0 -0
  122. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/Allocations.sysml +0 -0
  123. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/AnalysisCases.sysml +0 -0
  124. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/Attributes.sysml +0 -0
  125. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/Calculations.sysml +0 -0
  126. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/Cases.sysml +0 -0
  127. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/Connections.sysml +0 -0
  128. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/Constraints.sysml +0 -0
  129. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/Flows.sysml +0 -0
  130. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/Interfaces.sysml +0 -0
  131. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/Items.sysml +0 -0
  132. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/Metadata.sysml +0 -0
  133. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/Parts.sysml +0 -0
  134. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/Ports.sysml +0 -0
  135. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/Requirements.sysml +0 -0
  136. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/StandardViewDefinitions.sysml +0 -0
  137. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/States.sysml +0 -0
  138. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/SysML.sysml +0 -0
  139. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/UseCases.sysml +0 -0
  140. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/VerificationCases.sysml +0 -0
  141. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/library/systems/Views.sysml +0 -0
  142. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/navigate.py +0 -0
  143. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/project.py +0 -0
  144. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/semantic.py +0 -0
  145. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/store.py +0 -0
  146. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/us_customary_units.txt +0 -0
  147. {sysmlpy-0.33.2 → sysmlpy-0.33.4}/src/sysmlpy/validator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sysmlpy
3
- Version: 0.33.2
3
+ Version: 0.33.4
4
4
  Summary:
5
5
  License-File: LICENSE
6
6
  Author: Jon R. Fox (mycr0ft)
@@ -825,6 +825,19 @@ See [`docs/plantuml-examples/`](docs/plantuml-examples/) for all rendered exampl
825
825
 
826
826
  Rejected: `interface` as unquoted identifier (use `'interface'` per spec), guard after `then` in transitions (guard must precede `then` per spec).
827
827
 
828
+ - **v0.33.3** — Fix grid views for modern PlantUML, add two new views:
829
+ 1. PlantUML grid views (`as_tabular_view`, `as_data_value_tabular_view`, `as_relationship_matrix_view`) replaced deprecated salt syntax with rectangle-based layout, compatible with PlantUML 1.2024.7+.
830
+ 2. New `as_sequence_view()` — maps action flows and message passing onto PlantUML sequence diagram syntax (participant lifelines, `->` messages).
831
+ 3. New `as_case_view()` — maps actors and use cases onto PlantUML use-case diagram syntax.
832
+ 4. Added `docs/GUARDS.md` documenting guard condition syntax for confused users (canonical keyword is `if`, transition order is `accept` before `if` before `do` before `then`).
833
+
834
+ - **v0.33.4** — Fix `timeslice`/`snapshot`/`individual` parsing and PlantUML rendering:
835
+ 1. `portionUsage` and `individualUsage` were silently dropped from nested body definitions (visitor gaps in `_visit_nested_occurrence_usage`, `_visit_nested_usage`).
836
+ 2. Added `PortionUsage` grammar class and dispatch in `StructureUsageElement.__init__`.
837
+ 3. Added `_make_portion_usage_prefix()` to extract prefix info from `PortionUsageContext`.
838
+ 4. Added `load_from_grammar` handler for `PortionUsage` in `usage.py`.
839
+ 5. PlantUML `_get_stereotype()` now includes `individual`/`timeslice`/`snapshot` prefixes (e.g. `<<timeslice part>>`, `<<individual part>>`).
840
+
828
841
  ## Conformance
829
842
 
830
843
  **100% of 123 OMG XPect conformance tests pass** (123/123).
@@ -800,6 +800,19 @@ See [`docs/plantuml-examples/`](docs/plantuml-examples/) for all rendered exampl
800
800
 
801
801
  Rejected: `interface` as unquoted identifier (use `'interface'` per spec), guard after `then` in transitions (guard must precede `then` per spec).
802
802
 
803
+ - **v0.33.3** — Fix grid views for modern PlantUML, add two new views:
804
+ 1. PlantUML grid views (`as_tabular_view`, `as_data_value_tabular_view`, `as_relationship_matrix_view`) replaced deprecated salt syntax with rectangle-based layout, compatible with PlantUML 1.2024.7+.
805
+ 2. New `as_sequence_view()` — maps action flows and message passing onto PlantUML sequence diagram syntax (participant lifelines, `->` messages).
806
+ 3. New `as_case_view()` — maps actors and use cases onto PlantUML use-case diagram syntax.
807
+ 4. Added `docs/GUARDS.md` documenting guard condition syntax for confused users (canonical keyword is `if`, transition order is `accept` before `if` before `do` before `then`).
808
+
809
+ - **v0.33.4** — Fix `timeslice`/`snapshot`/`individual` parsing and PlantUML rendering:
810
+ 1. `portionUsage` and `individualUsage` were silently dropped from nested body definitions (visitor gaps in `_visit_nested_occurrence_usage`, `_visit_nested_usage`).
811
+ 2. Added `PortionUsage` grammar class and dispatch in `StructureUsageElement.__init__`.
812
+ 3. Added `_make_portion_usage_prefix()` to extract prefix info from `PortionUsageContext`.
813
+ 4. Added `load_from_grammar` handler for `PortionUsage` in `usage.py`.
814
+ 5. PlantUML `_get_stereotype()` now includes `individual`/`timeslice`/`snapshot` prefixes (e.g. `<<timeslice part>>`, `<<individual part>>`).
815
+
803
816
  ## Conformance
804
817
 
805
818
  **100% of 123 OMG XPect conformance tests pass** (123/123).
@@ -6,7 +6,7 @@ build-backend = "poetry.core.masonry.api"
6
6
 
7
7
  [project]
8
8
  name = "sysmlpy"
9
- version = "0.33.2"
9
+ version = "0.33.4"
10
10
  description = ""
11
11
  authors = [{ name = "Jon R. Fox (mycr0ft)", email = "jon.fox@drfox.com" }]
12
12
  readme = "README.md"
@@ -17,11 +17,12 @@ __all__ = [
17
17
  "as_general_view", "as_package_view", "as_package_diagram_view", "as_block_definition_view", "as_internal_block_diagram",
18
18
  "as_parametric_view", "as_requirement_view",
19
19
  "as_tabular_view", "as_data_value_tabular_view", "as_relationship_matrix_view",
20
+ "as_sequence_view", "as_case_view",
20
21
  "analyze", "AnalysisResult", "SemanticIssue", "SemanticAnalyzer",
21
22
  "SysMLSyntaxError",
22
23
  ]
23
24
  __author__ = "Jon Fox"
24
- __version__ = "0.33.2"
25
+ __version__ = "0.33.4"
25
26
 
26
27
  from sysmlpy.usage import (
27
28
  Item, Attribute, Part, Port, Action, Reference, UseCase, Requirement, Interface, Message,
@@ -261,7 +262,8 @@ from sysmlpy.plantuml import (to_plantuml, PlantUMLGenerator,
261
262
  as_action_flow_view, as_interconnection_view, as_state_transition_view,
262
263
  as_general_view, as_package_view, as_package_diagram_view, as_block_definition_view, as_internal_block_diagram,
263
264
  as_parametric_view, as_requirement_view,
264
- as_tabular_view, as_data_value_tabular_view, as_relationship_matrix_view)
265
+ as_tabular_view, as_data_value_tabular_view, as_relationship_matrix_view,
266
+ as_sequence_view, as_case_view)
265
267
 
266
268
  from sysmlpy.semantic import analyze, AnalysisResult, SemanticIssue, SemanticAnalyzer
267
269
 
@@ -1079,6 +1079,81 @@ def _get_occurrence_usage_prefix(ctx):
1079
1079
  }
1080
1080
 
1081
1081
 
1082
+ def _make_portion_usage_prefix(ctx):
1083
+ """Build an OccurrenceUsagePrefix dict from a PortionUsageContext.
1084
+
1085
+ PortionUsageContext has basicUsagePrefix directly (not via occurrenceUsagePrefix),
1086
+ plus optional INDIVIDUAL and required portionKind.
1087
+ """
1088
+ is_reference = False
1089
+ direction_in = ""
1090
+ direction_out = ""
1091
+ direction_inout = ""
1092
+ is_end = False
1093
+ is_individual = False
1094
+ portion_kind = None
1095
+
1096
+ if hasattr(ctx, 'basicUsagePrefix') and ctx.basicUsagePrefix():
1097
+ bup = ctx.basicUsagePrefix()
1098
+ is_reference = hasattr(bup, 'REF') and bup.REF() is not None
1099
+ if hasattr(bup, 'refPrefix') and bup.refPrefix():
1100
+ rp = bup.refPrefix()
1101
+ if hasattr(rp, 'featureDirection') and rp.featureDirection():
1102
+ fd = rp.featureDirection()
1103
+ direction_in = "in " if fd.IN() is not None else ""
1104
+ direction_out = "out" if fd.OUT() is not None else ""
1105
+ direction_inout = "inout" if fd.INOUT() is not None else ""
1106
+ if hasattr(rp, 'END') and rp.END() is not None:
1107
+ is_end = True
1108
+
1109
+ if hasattr(ctx, 'INDIVIDUAL') and ctx.INDIVIDUAL() is not None:
1110
+ is_individual = True
1111
+
1112
+ if hasattr(ctx, 'portionKind') and ctx.portionKind():
1113
+ pk_ctx = ctx.portionKind()
1114
+ if hasattr(pk_ctx, 'SNAPSHOT') and pk_ctx.SNAPSHOT() is not None:
1115
+ portion_kind = "snapshot"
1116
+ elif hasattr(pk_ctx, 'TIMESLICE') and pk_ctx.TIMESLICE() is not None:
1117
+ portion_kind = "timeslice"
1118
+
1119
+ ref_prefix = None
1120
+ has_direction = any([direction_in, direction_out, direction_inout])
1121
+ if has_direction or is_end:
1122
+ ref_prefix = {
1123
+ "name": "RefPrefix",
1124
+ "direction": {
1125
+ "name": "FeatureDirection",
1126
+ "in": direction_in,
1127
+ "out": direction_out,
1128
+ "inout": direction_inout
1129
+ },
1130
+ "isAbstract": None,
1131
+ "isVariation": None,
1132
+ "isReadOnly": None,
1133
+ "isDerived": None,
1134
+ "isEnd": "end" if is_end else None
1135
+ }
1136
+
1137
+ portion_kind_dict = None
1138
+ if portion_kind is not None:
1139
+ portion_kind_dict = {
1140
+ "name": "PortionKind",
1141
+ "kind": portion_kind
1142
+ }
1143
+
1144
+ return {
1145
+ "name": "OccurrenceUsagePrefix",
1146
+ "prefix": {
1147
+ "name": "BasicUsagePrefix",
1148
+ "prefix": ref_prefix,
1149
+ "isReference": is_reference
1150
+ },
1151
+ "isIndividual": "individual" if is_individual else None,
1152
+ "portionKind": portion_kind_dict,
1153
+ "usageExtension": []
1154
+ }
1155
+
1156
+
1082
1157
  def _get_occurrence_definition_prefix(ctx):
1083
1158
  """Extract OccurrenceDefinitionPrefix from a definition context (for 'abstract' etc.)."""
1084
1159
  is_abstract = False
@@ -9322,6 +9397,22 @@ def _visit_nested_occurrence_usage(occ_elem):
9322
9397
  inner = result.get("ownedRelatedElement", {})
9323
9398
  return inner
9324
9399
  return result
9400
+ elif hasattr(occ_elem, 'portionUsage') and occ_elem.portionUsage():
9401
+ ctx = occ_elem.portionUsage()
9402
+ name, shortname = _get_usage_identification(ctx)
9403
+ body_items = _get_usage_body_items(ctx)
9404
+ occ_prefix = _make_portion_usage_prefix(ctx)
9405
+ specialization = _build_full_specialization_from_ctx(ctx)
9406
+ valuepart = _get_usage_value_part(ctx)
9407
+ return _make_nested_usage_element("PortionUsage", name, shortname, occ_prefix, body_items, specialization, valuepart)
9408
+ elif hasattr(occ_elem, 'individualUsage') and occ_elem.individualUsage():
9409
+ ctx = occ_elem.individualUsage()
9410
+ name, shortname = _get_usage_identification(ctx)
9411
+ body_items = _get_usage_body_items(ctx)
9412
+ occ_prefix = _make_portion_usage_prefix(ctx)
9413
+ specialization = _build_full_specialization_from_ctx(ctx)
9414
+ valuepart = _get_usage_value_part(ctx)
9415
+ return _make_nested_usage_element("PortionUsage", name, shortname, occ_prefix, body_items, specialization, valuepart)
9325
9416
  return None
9326
9417
 
9327
9418
  # print(f"DEBUG _visit_nested_occurrence_usage: {type(occ_elem).__name__}")
@@ -9377,6 +9468,22 @@ def _visit_nested_occurrence_usage(occ_elem):
9377
9468
  elif hasattr(struct_elem, 'connectionUsage') and struct_elem.connectionUsage():
9378
9469
  ctx = struct_elem.connectionUsage()
9379
9470
  return _make_nested_connection_usage_dict(ctx, None)
9471
+ elif hasattr(struct_elem, 'portionUsage') and struct_elem.portionUsage():
9472
+ ctx = struct_elem.portionUsage()
9473
+ name, shortname = _get_usage_identification(ctx)
9474
+ body_items = _get_usage_body_items(ctx)
9475
+ occ_prefix = _make_portion_usage_prefix(ctx)
9476
+ specialization = _build_full_specialization_from_ctx(ctx)
9477
+ valuepart = _get_usage_value_part(ctx)
9478
+ return _make_nested_usage_element("PortionUsage", name, shortname, occ_prefix, body_items, specialization, valuepart)
9479
+ elif hasattr(struct_elem, 'individualUsage') and struct_elem.individualUsage():
9480
+ ctx = struct_elem.individualUsage()
9481
+ name, shortname = _get_usage_identification(ctx)
9482
+ body_items = _get_usage_body_items(ctx)
9483
+ occ_prefix = _make_portion_usage_prefix(ctx)
9484
+ specialization = _build_full_specialization_from_ctx(ctx)
9485
+ valuepart = _get_usage_value_part(ctx)
9486
+ return _make_nested_usage_element("PortionUsage", name, shortname, occ_prefix, body_items, specialization, valuepart)
9380
9487
 
9381
9488
  # Check for interface occurrence usage element (has defaultInterfaceEnd keyword)
9382
9489
  if hasattr(occ_elem, 'defaultInterfaceEnd') and occ_elem.defaultInterfaceEnd() is not None:
@@ -9625,6 +9732,22 @@ def _visit_nested_occurrence_usage(occ_elem):
9625
9732
  inner = result.get("ownedRelatedElement", {})
9626
9733
  return inner
9627
9734
  return result
9735
+ elif hasattr(struct_elem, 'portionUsage') and struct_elem.portionUsage():
9736
+ ctx = struct_elem.portionUsage()
9737
+ name, shortname = _get_usage_identification(ctx)
9738
+ body_items = _get_usage_body_items(ctx)
9739
+ occ_prefix = _make_portion_usage_prefix(ctx)
9740
+ specialization = _build_full_specialization_from_ctx(ctx)
9741
+ valuepart = _get_usage_value_part(ctx)
9742
+ return _make_nested_usage_element("PortionUsage", name, shortname, occ_prefix, body_items, specialization, valuepart)
9743
+ elif hasattr(struct_elem, 'individualUsage') and struct_elem.individualUsage():
9744
+ ctx = struct_elem.individualUsage()
9745
+ name, shortname = _get_usage_identification(ctx)
9746
+ body_items = _get_usage_body_items(ctx)
9747
+ occ_prefix = _make_portion_usage_prefix(ctx)
9748
+ specialization = _build_full_specialization_from_ctx(ctx)
9749
+ valuepart = _get_usage_value_part(ctx)
9750
+ return _make_nested_usage_element("PortionUsage", name, shortname, occ_prefix, body_items, specialization, valuepart)
9628
9751
 
9629
9752
  # Check behavior usage elements (action)
9630
9753
  if hasattr(occ_elem, 'behaviorUsageElement') and occ_elem.behaviorUsageElement():
@@ -10653,6 +10776,22 @@ def _visit_nested_usage(usage_elem_ctx):
10653
10776
  specialization = _build_full_specialization_from_ctx(ctx)
10654
10777
  valuepart = _get_usage_value_part(ctx)
10655
10778
  return _make_nested_usage_element("PortUsage", name, shortname, occ_prefix, body_items, specialization, valuepart)
10779
+ elif hasattr(struct_elem, 'portionUsage') and struct_elem.portionUsage():
10780
+ ctx = struct_elem.portionUsage()
10781
+ name, shortname = _get_usage_identification(ctx)
10782
+ body_items = _get_usage_body_items(ctx)
10783
+ occ_prefix = _make_portion_usage_prefix(ctx)
10784
+ specialization = _build_full_specialization_from_ctx(ctx)
10785
+ valuepart = _get_usage_value_part(ctx)
10786
+ return _make_nested_usage_element("PortionUsage", name, shortname, occ_prefix, body_items, specialization, valuepart)
10787
+ elif hasattr(struct_elem, 'individualUsage') and struct_elem.individualUsage():
10788
+ ctx = struct_elem.individualUsage()
10789
+ name, shortname = _get_usage_identification(ctx)
10790
+ body_items = _get_usage_body_items(ctx)
10791
+ occ_prefix = _make_portion_usage_prefix(ctx)
10792
+ specialization = _build_full_specialization_from_ctx(ctx)
10793
+ valuepart = _get_usage_value_part(ctx)
10794
+ return _make_nested_usage_element("PortionUsage", name, shortname, occ_prefix, body_items, specialization, valuepart)
10656
10795
 
10657
10796
  # Check behavior usage elements (action)
10658
10797
  if hasattr(occ_elem, 'behaviorUsageElement') and occ_elem.behaviorUsageElement():
@@ -10837,6 +10976,21 @@ def _visit_usage_element_dict(usage_elem_ctx, prefix=None):
10837
10976
  elif hasattr(struct_elem, 'individualUsage') and struct_elem.individualUsage():
10838
10977
  ctx = struct_elem.individualUsage()
10839
10978
  return _make_individual_usage_dict(ctx, prefix)
10979
+ elif hasattr(struct_elem, 'portionUsage') and struct_elem.portionUsage():
10980
+ ctx = struct_elem.portionUsage()
10981
+ name, shortname = _get_usage_identification(ctx)
10982
+ body_items = _get_usage_body_items(ctx)
10983
+ occ_prefix = _make_portion_usage_prefix(ctx)
10984
+ specialization = _build_full_specialization_from_ctx(ctx)
10985
+ valuepart = _get_usage_value_part(ctx)
10986
+ inner = _make_nested_usage_element("PortionUsage", name, shortname, occ_prefix, body_items, specialization, valuepart)
10987
+ if inner:
10988
+ return {
10989
+ "name": "PackageMember",
10990
+ "prefix": None,
10991
+ "ownedRelatedElement": inner
10992
+ }
10993
+ return None
10840
10994
  elif hasattr(struct_elem, 'viewUsage') and struct_elem.viewUsage():
10841
10995
  ctx = struct_elem.viewUsage()
10842
10996
  return _make_view_usage_dict(ctx, prefix)
@@ -6298,6 +6298,8 @@ class StructureUsageElement:
6298
6298
  self.children = AllocationUsage(definition["ownedRelatedElement"])
6299
6299
  elif name == "RenderingUsage":
6300
6300
  self.children = RenderingUsage(definition["ownedRelatedElement"])
6301
+ elif name == "PortionUsage":
6302
+ self.children = PortionUsage(definition["ownedRelatedElement"])
6301
6303
  elif name == "ViewUsage":
6302
6304
  self.children = ViewUsage(definition["ownedRelatedElement"])
6303
6305
  elif name == "SuccessionFlowConnectionUsage":
@@ -9615,6 +9617,40 @@ class IndividualUsageSimple(_PrefixedUsageBase):
9615
9617
  keyword = "individual"
9616
9618
 
9617
9619
 
9620
+ class PortionUsage:
9621
+ """Portion usage (timeslice or snapshot) inside a body."""
9622
+
9623
+ def __init__(self, definition=None):
9624
+ if definition is not None:
9625
+ if valid_definition(definition, "PortionUsage"):
9626
+ if definition.get("prefix") is not None:
9627
+ prefix_name = definition["prefix"].get("name", "OccurrenceUsagePrefix")
9628
+ self.prefix = globals()[prefix_name](definition["prefix"])
9629
+ else:
9630
+ self.prefix = None
9631
+ self.usage = Usage(definition.get("usage"))
9632
+ else:
9633
+ self.prefix = None
9634
+ self.usage = Usage()
9635
+
9636
+ def dump(self):
9637
+ output = []
9638
+ if self.prefix is not None:
9639
+ output.append(self.prefix.dump())
9640
+ if self.usage is not None:
9641
+ output.append(self.usage.dump())
9642
+ return " ".join(output)
9643
+
9644
+ def get_definition(self):
9645
+ pre = None
9646
+ if self.prefix is not None:
9647
+ pre = self.prefix.get_definition()
9648
+ u = None
9649
+ if self.usage is not None:
9650
+ u = self.usage.get_definition()
9651
+ return {"name": self.__class__.__name__, "prefix": pre, "usage": u}
9652
+
9653
+
9618
9654
  class FlowUsageSimple(_PrefixedUsageBase):
9619
9655
  """Alternative FlowUsage (flow without connection - simple usage)."""
9620
9656
  keyword = "flow"