lino 24.11.0__py3-none-any.whl → 24.11.1__py3-none-any.whl

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 (54) hide show
  1. lino/__init__.py +1 -1
  2. lino/core/actions.py +2 -4
  3. lino/core/actors.py +2 -2
  4. lino/core/dbtables.py +12 -12
  5. lino/core/fields.py +1 -0
  6. lino/core/inject.py +9 -2
  7. lino/core/kernel.py +7 -6
  8. lino/core/model.py +24 -27
  9. lino/core/renderer.py +2 -2
  10. lino/core/requests.py +21 -45
  11. lino/core/site.py +4 -45
  12. lino/core/store.py +4 -4
  13. lino/core/utils.py +5 -2
  14. lino/help_texts.py +4 -3
  15. lino/locale/bn/LC_MESSAGES/django.po +1210 -907
  16. lino/locale/de/LC_MESSAGES/django.po +1760 -1375
  17. lino/locale/django.pot +1136 -906
  18. lino/locale/es/LC_MESSAGES/django.po +1709 -1347
  19. lino/locale/et/LC_MESSAGES/django.po +1206 -906
  20. lino/locale/fr/LC_MESSAGES/django.mo +0 -0
  21. lino/locale/fr/LC_MESSAGES/django.po +1193 -923
  22. lino/locale/nl/LC_MESSAGES/django.po +1247 -942
  23. lino/locale/pt_BR/LC_MESSAGES/django.po +1190 -903
  24. lino/locale/zh_Hant/LC_MESSAGES/django.po +1190 -903
  25. lino/mixins/periods.py +6 -4
  26. lino/modlib/comments/choicelists.py +1 -1
  27. lino/modlib/comments/fixtures/demo2.py +4 -1
  28. lino/modlib/comments/mixins.py +9 -10
  29. lino/modlib/comments/models.py +4 -4
  30. lino/modlib/comments/ui.py +5 -0
  31. lino/modlib/linod/mixins.py +3 -2
  32. lino/modlib/memo/mixins.py +10 -208
  33. lino/modlib/notify/mixins.py +33 -32
  34. lino/modlib/periods/mixins.py +0 -1
  35. lino/modlib/printing/choicelists.py +3 -3
  36. lino/modlib/search/models.py +17 -11
  37. lino/modlib/system/fixtures/__init__.py +0 -0
  38. lino/modlib/system/fixtures/std.py +5 -0
  39. lino/modlib/system/models.py +3 -2
  40. lino/modlib/uploads/__init__.py +10 -1
  41. lino/modlib/uploads/choicelists.py +3 -3
  42. lino/modlib/uploads/mixins.py +30 -32
  43. lino/modlib/uploads/models.py +89 -56
  44. lino/modlib/uploads/ui.py +12 -6
  45. lino/modlib/uploads/utils.py +107 -0
  46. lino/utils/__init__.py +6 -0
  47. lino/utils/html.py +1 -1
  48. lino/utils/media.py +2 -3
  49. lino/utils/soup.py +311 -0
  50. {lino-24.11.0.dist-info → lino-24.11.1.dist-info}/METADATA +1 -3
  51. {lino-24.11.0.dist-info → lino-24.11.1.dist-info}/RECORD +54 -50
  52. {lino-24.11.0.dist-info → lino-24.11.1.dist-info}/WHEEL +1 -1
  53. {lino-24.11.0.dist-info → lino-24.11.1.dist-info}/licenses/AUTHORS.rst +0 -0
  54. {lino-24.11.0.dist-info → lino-24.11.1.dist-info}/licenses/COPYING +0 -0
lino/mixins/periods.py CHANGED
@@ -204,6 +204,7 @@ class Ended(CombinedDateTime):
204
204
 
205
205
 
206
206
  class DateRangeObservable(Model):
207
+
207
208
  class Meta(object):
208
209
  abstract = True
209
210
 
@@ -235,8 +236,9 @@ class DateRangeObservable(Model):
235
236
 
236
237
  class DateRange(DateRangeObservable):
237
238
  """
238
- Mixin for models that represent a period defined by a start date and an end
239
- date.
239
+
240
+ A model mixin that adds two fields `start_date` and `end_date`.
241
+ :class:`DateRangeObservable`
240
242
 
241
243
  Designed for usage with
242
244
  :class:`lino.modlib.system.PeriodEvents`.
@@ -280,9 +282,9 @@ DateRange.set_widget_options("end_date", width=10)
280
282
 
281
283
  class ObservedDateRange(ParameterPanel):
282
284
  """:class:`lino.core.param_panel.ParameterPanel` with two fields
283
- `start_date` and `end_date` which default to empty.
285
+ `start_date` and `end_date`.
284
286
 
285
- Note that you must define yourself a get_request_queryset method in order to
287
+ You must define yourself a :meth:`get_request_queryset` method in order to
286
288
  actually use these two parameter fields.
287
289
 
288
290
  """
@@ -33,7 +33,7 @@ elif emotion_range == "social":
33
33
 
34
34
  class ObservedTime(ObservedEvent):
35
35
  def __init__(self, value, name, text):
36
- super(ObservedTime, self).__init__(value, text=text, name=name)
36
+ super().__init__(value, text=text, name=name)
37
37
 
38
38
  def add_filter(self, qs, pv):
39
39
  if pv.start_date:
@@ -14,6 +14,7 @@ from django.utils.timezone import make_aware
14
14
  from lino.modlib.comments.mixins import Commentable
15
15
 
16
16
  styled = """<h1 style="color: #5e9ca0;">Styled comment <span style="color: #2b2301;">pasted from word!</span> </h1>"""
17
+
17
18
  table = """<table class="editorDemoTable"><thead>
18
19
  <tr><td>Who</td><td>What</td><td>Done?</td></tr></thead><tbody><tr><td>Him</td><td>Bar</td><td>&nbsp;</td></tr><tr><td>Her</td><td>Foo the Bar</td><td><strong style="font-size: 17px; color: #2b2301;">x</strong></td></tr><tr><td>Them</td><td><span id="demoId">Floop the pig<br /></span></td><td>x</td></tr></tbody></table>"""
19
20
  lorem = """<p>Lorem ipsum <strong> dolor sit amet</strong>, consectetur adipiscing elit. Nunc cursus felis nisi, eu pellentesque lorem lobortis non. Aenean non sodales neque, vitae venenatis lectus. In eros dui, gravida et dolor at, pellentesque hendrerit magna. Quisque vel lectus dictum, rhoncus massa feugiat, condimentum sem. Donec elit nisl, placerat vitae imperdiet eget, hendrerit nec quam. Ut elementum ligula vitae odio efficitur rhoncus. Duis in blandit neque. Sed dictum mollis volutpat. Morbi at est et nisi euismod viverra. Nulla quis lacus vitae ante sollicitudin tincidunt. Donec nec enim in leo vulputate ultrices. Suspendisse potenti. Ut elit nibh, porta ut enim ac, convallis molestie risus. Praesent consectetur lacus lacus, in faucibus justo fringilla vel.</p>
@@ -22,7 +23,8 @@ short_lorem = """<p>Lorem ipsum <strong> dolor sit amet</strong>, consectetur ad
22
23
  <p>Phasellus gravida ullamcorper eros, sit amet blandit sapien laoreet quis.</p>
23
24
  <p>Donec accumsan mauris at risus lobortis, nec pretium tortor aliquam. Nulla vel enim vel eros venenatis congue.</p>"""
24
25
 
25
- breaking = '<p>breaking <!--[if gte mso 9]><xml>\n <o:OfficeDocumentSettings>\n <o:AllowPNG/>\n </o:OfficeDocumentSettings>\n</xml><![endif]--></p>\n<p><!--[if gte mso 9]><xml>\n <w:WordDocument>\n <w:View>Normal</w:View>\n <w:Zoom>0</w:Zoom>\n <w:TrackMoves/>\n <w:TrackFormatting/>\n <w:HyphenationZone>21</w:HyphenationZone>\n <w:PunctuationKerning/>\n <w:ValidateAgainstSchemas/>\n <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>\n <w:IgnoreMixedContent>false</w:IgnoreMixedContent>\n <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>\n <w:DoNotPromoteQF/>\n <w:LidThemeOther>FR-BE</w:LidThemeOther>\n <w:LidThemeAsian>X-NONE</w:LidThemeAsian>\n <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>\n <w:Compatibility>\n <w:BreakWrappedTables/>\n <w:SnapToGridInCell/>\n <w:WrapTextWithPunct/>\n <w:UseAsianBreakRules/>\n <w:DontGrowAutofit/>\n <w:SplitPgBreakAndParaMark/>\n <w:EnableOpenTypeKerning/>\n <w:DontFlipMirrorIndents/>\n <w:OverrideTableStyleHps/>\n </w:Compatibility>\n <m:mathPr>\n <m:mathFont m:val="Cambria Math"/>\n <m:brkBin m:val="before"/>\n <m:brkBinSub m:val="&#45;-"/>\n <m:smallFrac m:val="off"/>\n <m:dispDef/>\n <m:lMargin m:val="0"/>\n <m:rMargin m:val="0"/>\n <m:defJc m:val="centerGroup"/>\n <m:wrapIndent m:val="1440"/>\n <m:intLim m:val="subSup"/>\n <m:naryLim m:val="undOvr"/>\n </m:mathPr></w:WordDocument>\n</xml><![endif]--><!--[if gte mso 9]><xml>\n <w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true"\n DefSemiHidden="true" DefQFormat="false" DefPriority="99"\n LatentStyleCount="267">\n <w:LsdException Locked="false" Priority="0" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Normal"/>\n <w:LsdException Locked="false" Priority="9" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="heading 1"/>\n <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2"/>\n <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3"/>\n <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 4"/>\n <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 5"/>\n <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 6"/>\n <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 7"/>\n <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 8"/>\n <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 9"/>\n <w:LsdException Locked="false" Priority="39" Name="toc 1"/>\n <w:LsdException Locked="false" Priority="39" Name="toc 2"/>\n <w:LsdException Locked="false" Priority="39" Name="toc 3"/>\n <w:LsdException Locked="false" Priority="39" Name="toc 4"/>\n <w:LsdException Locked="false" Priority="39" Name="toc 5"/>\n <w:LsdException Locked="false" Priority="39" Name="toc 6"/>\n <w:LsdException Locked="false" Priority="39" Name="toc 7"/>\n <w:LsdException Locked="false" Priority="39" Name="toc 8"/>\n <w:LsdException Locked="false" Priority="39" Name="toc 9"/>\n <w:LsdException Locked="false" Priority="35" QFormat="true" Name="caption"/>\n <w:LsdException Locked="false" Priority="10" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Title"/>\n <w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font"/>\n <w:LsdException Locked="false" Priority="11" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Subtitle"/>\n <w:LsdException Locked="false" Priority="22" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Strong"/>\n <w:LsdException Locked="false" Priority="20" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Emphasis"/>\n <w:LsdException Locked="false" Priority="59" SemiHidden="false"\n UnhideWhenUsed="false" Name="Table Grid"/>\n <w:LsdException Locked="false" UnhideWhenUsed="false" Name="Placeholder Text"/>\n <w:LsdException Locked="false" Priority="1" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="No Spacing"/>\n <w:LsdException Locked="false" Priority="60" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Shading"/>\n <w:LsdException Locked="false" Priority="61" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light List"/>\n <w:LsdException Locked="false" Priority="62" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Grid"/>\n <w:LsdException Locked="false" Priority="63" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 1"/>\n <w:LsdException Locked="false" Priority="64" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 2"/>\n <w:LsdException Locked="false" Priority="65" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 1"/>\n <w:LsdException Locked="false" Priority="66" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 2"/>\n <w:LsdException Locked="false" Priority="67" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 1"/>\n <w:LsdException Locked="false" Priority="68" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 2"/>\n <w:LsdException Locked="false" Priority="69" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 3"/>\n <w:LsdException Locked="false" Priority="70" SemiHidden="false"\n UnhideWhenUsed="false" Name="Dark List"/>\n <w:LsdException Locked="false" Priority="71" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Shading"/>\n <w:LsdException Locked="false" Priority="72" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful List"/>\n <w:LsdException Locked="false" Priority="73" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Grid"/>\n <w:LsdException Locked="false" Priority="60" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Shading Accent 1"/>\n <w:LsdException Locked="false" Priority="61" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light List Accent 1"/>\n <w:LsdException Locked="false" Priority="62" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Grid Accent 1"/>\n <w:LsdException Locked="false" Priority="63" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1"/>\n <w:LsdException Locked="false" Priority="64" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1"/>\n <w:LsdException Locked="false" Priority="65" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 1 Accent 1"/>\n <w:LsdException Locked="false" UnhideWhenUsed="false" Name="Revision"/>\n <w:LsdException Locked="false" Priority="34" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="List Paragraph"/>\n <w:LsdException Locked="false" Priority="29" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Quote"/>\n <w:LsdException Locked="false" Priority="30" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Intense Quote"/>\n <w:LsdException Locked="false" Priority="66" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 2 Accent 1"/>\n <w:LsdException Locked="false" Priority="67" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1"/>\n <w:LsdException Locked="false" Priority="68" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1"/>\n <w:LsdException Locked="false" Priority="69" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1"/>\n <w:LsdException Locked="false" Priority="70" SemiHidden="false"\n UnhideWhenUsed="false" Name="Dark List Accent 1"/>\n <w:LsdException Locked="false" Priority="71" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Shading Accent 1"/>\n <w:LsdException Locked="false" Priority="72" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful List Accent 1"/>\n <w:LsdException Locked="false" Priority="73" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Grid Accent 1"/>\n <w:LsdException Locked="false" Priority="60" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Shading Accent 2"/>\n <w:LsdException Locked="false" Priority="61" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light List Accent 2"/>\n <w:LsdException Locked="false" Priority="62" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Grid Accent 2"/>\n <w:LsdException Locked="false" Priority="63" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2"/>\n <w:LsdException Locked="false" Priority="64" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2"/>\n <w:LsdException Locked="false" Priority="65" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 1 Accent 2"/>\n <w:LsdException Locked="false" Priority="66" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 2 Accent 2"/>\n <w:LsdException Locked="false" Priority="67" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2"/>\n <w:LsdException Locked="false" Priority="68" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2"/>\n <w:LsdException Locked="false" Priority="69" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2"/>\n <w:LsdException Locked="false" Priority="70" SemiHidden="false"\n UnhideWhenUsed="false" Name="Dark List Accent 2"/>\n <w:LsdException Locked="false" Priority="71" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Shading Accent 2"/>\n <w:LsdException Locked="false" Priority="72" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful List Accent 2"/>\n <w:LsdException Locked="false" Priority="73" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Grid Accent 2"/>\n <w:LsdException Locked="false" Priority="60" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Shading Accent 3"/>\n <w:LsdException Locked="false" Priority="61" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light List Accent 3"/>\n <w:LsdException Locked="false" Priority="62" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Grid Accent 3"/>\n <w:LsdException Locked="false" Priority="63" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3"/>\n <w:LsdException Locked="false" Priority="64" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3"/>\n <w:LsdException Locked="false" Priority="65" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 1 Accent 3"/>\n <w:LsdException Locked="false" Priority="66" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 2 Accent 3"/>\n <w:LsdException Locked="false" Priority="67" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3"/>\n <w:LsdException Locked="false" Priority="68" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3"/>\n <w:LsdException Locked="false" Priority="69" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3"/>\n <w:LsdException Locked="false" Priority="70" SemiHidden="false"\n UnhideWhenUsed="false" Name="Dark List Accent 3"/>\n <w:LsdException Locked="false" Priority="71" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Shading Accent 3"/>\n <w:LsdException Locked="false" Priority="72" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful List Accent 3"/>\n <w:LsdException Locked="false" Priority="73" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Grid Accent 3"/>\n <w:LsdException Locked="false" Priority="60" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Shading Accent 4"/>\n <w:LsdException Locked="false" Priority="61" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light List Accent 4"/>\n <w:LsdException Locked="false" Priority="62" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Grid Accent 4"/>\n <w:LsdException Locked="false" Priority="63" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4"/>\n <w:LsdException Locked="false" Priority="64" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4"/>\n <w:LsdException Locked="false" Priority="65" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 1 Accent 4"/>\n <w:LsdException Locked="false" Priority="66" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 2 Accent 4"/>\n <w:LsdException Locked="false" Priority="67" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4"/>\n <w:LsdException Locked="false" Priority="68" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4"/>\n <w:LsdException Locked="false" Priority="69" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4"/>\n <w:LsdException Locked="false" Priority="70" SemiHidden="false"\n UnhideWhenUsed="false" Name="Dark List Accent 4"/>\n <w:LsdException Locked="false" Priority="71" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Shading Accent 4"/>\n <w:LsdException Locked="false" Priority="72" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful List Accent 4"/>\n <w:LsdException Locked="false" Priority="73" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Grid Accent 4"/>\n <w:LsdException Locked="false" Priority="60" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Shading Accent 5"/>\n <w:LsdException Locked="false" Priority="61" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light List Accent 5"/>\n <w:LsdException Locked="false" Priority="62" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Grid Accent 5"/>\n <w:LsdException Locked="false" Priority="63" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5"/>\n <w:LsdException Locked="false" Priority="64" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5"/>\n <w:LsdException Locked="false" Priority="65" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 1 Accent 5"/>\n <w:LsdException Locked="false" Priority="66" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 2 Accent 5"/>\n <w:LsdException Locked="false" Priority="67" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5"/>\n <w:LsdException Locked="false" Priority="68" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5"/>\n <w:LsdException Locked="false" Priority="69" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5"/>\n <w:LsdException Locked="false" Priority="70" SemiHidden="false"\n UnhideWhenUsed="false" Name="Dark List Accent 5"/>\n <w:LsdException Locked="false" Priority="71" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Shading Accent 5"/>\n <w:LsdException Locked="false" Priority="72" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful List Accent 5"/>\n <w:LsdException Locked="false" Priority="73" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Grid Accent 5"/>\n <w:LsdException Locked="false" Priority="60" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Shading Accent 6"/>\n <w:LsdException Locked="false" Priority="61" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light List Accent 6"/>\n <w:LsdException Locked="false" Priority="62" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Grid Accent 6"/>\n <w:LsdException Locked="false" Priority="63" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6"/>\n <w:LsdException Locked="false" Priority="64" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6"/>\n <w:LsdException Locked="false" Priority="65" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 1 Accent 6"/>\n <w:LsdException Locked="false" Priority="66" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 2 Accent 6"/>\n <w:LsdException Locked="false" Priority="67" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6"/>\n <w:LsdException Locked="false" Priority="68" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6"/>\n <w:LsdException Locked="false" Priority="69" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6"/>\n <w:LsdException Locked="false" Priority="70" SemiHidden="false"\n UnhideWhenUsed="false" Name="Dark List Accent 6"/>\n <w:LsdException Locked="false" Priority="71" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Shading Accent 6"/>\n <w:LsdException Locked="false" Priority="72" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful List Accent 6"/>\n <w:LsdException Locked="false" Priority="73" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Grid Accent 6"/>\n <w:LsdException Locked="false" Priority="19" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis"/>\n <w:LsdException Locked="false" Priority="21" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis"/>\n <w:LsdException Locked="false" Priority="31" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference"/>\n <w:LsdException Locked="false" Priority="32" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Intense Reference"/>\n <w:LsdException Locked="false" Priority="33" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Book Title"/>\n <w:LsdException Locked="false" Priority="37" Name="Bibliography"/>\n <w:LsdException Locked="false" Priority="39" QFormat="true" Name="TOC Heading"/>\n </w:LatentStyles>\n</xml><![endif]--><!--[if gte mso 10]>\n<style>\n /* Style Definitions */\n table.MsoNormalTable\n\t{mso-style-name:"Tableau Normal";\n\tmso-tstyle-rowband-size:0;\n\tmso-tstyle-colband-size:0;\n\tmso-style-noshow:yes;\n\tmso-style-priority:99;\n\tmso-style-parent:"";\n\tmso-padding-alt:0cm 5.4pt 0cm 5.4pt;\n\tmso-para-margin:0cm;\n\tmso-para-margin-bottom:.0001pt;\n\tmso-pagination:widow-orphan;\n\tfont-size:10.0pt;\n\tfont-family:"Times New Roman","serif";}\n</style>\n<![endif]--></p>\n<p class="MsoNormal" style="mso-outline-level: 1;"><strong><span style="font-size: 11.0pt; font-family: \'Calibri\',\'sans-serif\'; mso-ansi-language: FR;" lang="FR">De&nbsp;:</span></strong><span style="font-size: 11.0pt; font-family: \'Calibri\',\'sans-serif\'; mso-ansi-language: FR;" lang="FR"> <a href="mailto:lino@foo.net">lino@foo.net</a> [<a href="mailto:foo@bar.com">mailto:foo@bar.com</a>] <br /> <strong>Envoy&eacute;&nbsp;:</strong> mardi 18 octobre 2016 08:52<br /> <strong>&Agrave;&nbsp;:</strong> <a href="mailto:Far@baz.net">eexample@foo.com</a><br /> <strong>Objet&nbsp;:</strong> [welcht] YOU modified FOO BAR</span></p>\n<p class="MsoNormal">&nbsp;</p>\n<p>Dear Aur&eacute;lie ,</p>\n<p>this is to notify / BAR</p>\n<p>BAR modified </p>\n<p>TODO: include a summary of the modifications.</p>\n<p>Any subsequent notifications about foo/ until you view this notification in the Lino web interface. Please visit</p>\n<p class="MsoNormal"><a href="None">None</a></p>\n<p>and follow your welcome messages.</p>'
26
+ breaking = """<p>breaking <!--[if gte mso 9]><xml>\n <o:OfficeDocumentSettings>\n <o:AllowPNG/>\n </o:OfficeDocumentSettings>\n</xml><![endif]--></p>\n<p><!--[if gte mso 9]><xml>\n <w:WordDocument>\n <w:View>Normal</w:View>\n <w:Zoom>0</w:Zoom>\n <w:TrackMoves/>\n <w:TrackFormatting/>\n <w:HyphenationZone>21</w:HyphenationZone>\n <w:PunctuationKerning/>\n <w:ValidateAgainstSchemas/>\n <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>\n <w:IgnoreMixedContent>false</w:IgnoreMixedContent>\n <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>\n <w:DoNotPromoteQF/>\n <w:LidThemeOther>FR-BE</w:LidThemeOther>\n <w:LidThemeAsian>X-NONE</w:LidThemeAsian>\n <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>\n <w:Compatibility>\n <w:BreakWrappedTables/>\n <w:SnapToGridInCell/>\n <w:WrapTextWithPunct/>\n <w:UseAsianBreakRules/>\n <w:DontGrowAutofit/>\n <w:SplitPgBreakAndParaMark/>\n <w:EnableOpenTypeKerning/>\n <w:DontFlipMirrorIndents/>\n <w:OverrideTableStyleHps/>\n </w:Compatibility>\n <m:mathPr>\n <m:mathFont m:val="Cambria Math"/>\n <m:brkBin m:val="before"/>\n <m:brkBinSub m:val="&#45;-"/>\n <m:smallFrac m:val="off"/>\n <m:dispDef/>\n <m:lMargin m:val="0"/>\n <m:rMargin m:val="0"/>\n <m:defJc m:val="centerGroup"/>\n <m:wrapIndent m:val="1440"/>\n <m:intLim m:val="subSup"/>\n <m:naryLim m:val="undOvr"/>\n </m:mathPr></w:WordDocument>\n</xml><![endif]--><!--[if gte mso 9]><xml>\n <w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true"\n DefSemiHidden="true" DefQFormat="false" DefPriority="99"\n LatentStyleCount="267">\n <w:LsdException Locked="false" Priority="0" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Normal"/>\n <w:LsdException Locked="false" Priority="9" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="heading 1"/>\n <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2"/>\n <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3"/>\n <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 4"/>\n <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 5"/>\n <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 6"/>\n <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 7"/>\n <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 8"/>\n <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 9"/>\n <w:LsdException Locked="false" Priority="39" Name="toc 1"/>\n <w:LsdException Locked="false" Priority="39" Name="toc 2"/>\n <w:LsdException Locked="false" Priority="39" Name="toc 3"/>\n <w:LsdException Locked="false" Priority="39" Name="toc 4"/>\n <w:LsdException Locked="false" Priority="39" Name="toc 5"/>\n <w:LsdException Locked="false" Priority="39" Name="toc 6"/>\n <w:LsdException Locked="false" Priority="39" Name="toc 7"/>\n <w:LsdException Locked="false" Priority="39" Name="toc 8"/>\n <w:LsdException Locked="false" Priority="39" Name="toc 9"/>\n <w:LsdException Locked="false" Priority="35" QFormat="true" Name="caption"/>\n <w:LsdException Locked="false" Priority="10" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Title"/>\n <w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font"/>\n <w:LsdException Locked="false" Priority="11" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Subtitle"/>\n <w:LsdException Locked="false" Priority="22" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Strong"/>\n <w:LsdException Locked="false" Priority="20" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Emphasis"/>\n <w:LsdException Locked="false" Priority="59" SemiHidden="false"\n UnhideWhenUsed="false" Name="Table Grid"/>\n <w:LsdException Locked="false" UnhideWhenUsed="false" Name="Placeholder Text"/>\n <w:LsdException Locked="false" Priority="1" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="No Spacing"/>\n <w:LsdException Locked="false" Priority="60" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Shading"/>\n <w:LsdException Locked="false" Priority="61" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light List"/>\n <w:LsdException Locked="false" Priority="62" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Grid"/>\n <w:LsdException Locked="false" Priority="63" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 1"/>\n <w:LsdException Locked="false" Priority="64" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 2"/>\n <w:LsdException Locked="false" Priority="65" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 1"/>\n <w:LsdException Locked="false" Priority="66" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 2"/>\n <w:LsdException Locked="false" Priority="67" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 1"/>\n <w:LsdException Locked="false" Priority="68" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 2"/>\n <w:LsdException Locked="false" Priority="69" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 3"/>\n <w:LsdException Locked="false" Priority="70" SemiHidden="false"\n UnhideWhenUsed="false" Name="Dark List"/>\n <w:LsdException Locked="false" Priority="71" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Shading"/>\n <w:LsdException Locked="false" Priority="72" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful List"/>\n <w:LsdException Locked="false" Priority="73" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Grid"/>\n <w:LsdException Locked="false" Priority="60" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Shading Accent 1"/>\n <w:LsdException Locked="false" Priority="61" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light List Accent 1"/>\n <w:LsdException Locked="false" Priority="62" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Grid Accent 1"/>\n <w:LsdException Locked="false" Priority="63" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1"/>\n <w:LsdException Locked="false" Priority="64" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1"/>\n <w:LsdException Locked="false" Priority="65" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 1 Accent 1"/>\n <w:LsdException Locked="false" UnhideWhenUsed="false" Name="Revision"/>\n <w:LsdException Locked="false" Priority="34" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="List Paragraph"/>\n <w:LsdException Locked="false" Priority="29" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Quote"/>\n <w:LsdException Locked="false" Priority="30" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Intense Quote"/>\n <w:LsdException Locked="false" Priority="66" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 2 Accent 1"/>\n <w:LsdException Locked="false" Priority="67" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1"/>\n <w:LsdException Locked="false" Priority="68" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1"/>\n <w:LsdException Locked="false" Priority="69" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1"/>\n <w:LsdException Locked="false" Priority="70" SemiHidden="false"\n UnhideWhenUsed="false" Name="Dark List Accent 1"/>\n <w:LsdException Locked="false" Priority="71" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Shading Accent 1"/>\n <w:LsdException Locked="false" Priority="72" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful List Accent 1"/>\n <w:LsdException Locked="false" Priority="73" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Grid Accent 1"/>\n <w:LsdException Locked="false" Priority="60" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Shading Accent 2"/>\n <w:LsdException Locked="false" Priority="61" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light List Accent 2"/>\n <w:LsdException Locked="false" Priority="62" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Grid Accent 2"/>\n <w:LsdException Locked="false" Priority="63" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2"/>\n <w:LsdException Locked="false" Priority="64" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2"/>\n <w:LsdException Locked="false" Priority="65" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 1 Accent 2"/>\n <w:LsdException Locked="false" Priority="66" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 2 Accent 2"/>\n <w:LsdException Locked="false" Priority="67" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2"/>\n <w:LsdException Locked="false" Priority="68" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2"/>\n <w:LsdException Locked="false" Priority="69" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2"/>\n <w:LsdException Locked="false" Priority="70" SemiHidden="false"\n UnhideWhenUsed="false" Name="Dark List Accent 2"/>\n <w:LsdException Locked="false" Priority="71" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Shading Accent 2"/>\n <w:LsdException Locked="false" Priority="72" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful List Accent 2"/>\n <w:LsdException Locked="false" Priority="73" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Grid Accent 2"/>\n <w:LsdException Locked="false" Priority="60" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Shading Accent 3"/>\n <w:LsdException Locked="false" Priority="61" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light List Accent 3"/>\n <w:LsdException Locked="false" Priority="62" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Grid Accent 3"/>\n <w:LsdException Locked="false" Priority="63" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3"/>\n <w:LsdException Locked="false" Priority="64" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3"/>\n <w:LsdException Locked="false" Priority="65" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 1 Accent 3"/>\n <w:LsdException Locked="false" Priority="66" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 2 Accent 3"/>\n <w:LsdException Locked="false" Priority="67" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3"/>\n <w:LsdException Locked="false" Priority="68" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3"/>\n <w:LsdException Locked="false" Priority="69" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3"/>\n <w:LsdException Locked="false" Priority="70" SemiHidden="false"\n UnhideWhenUsed="false" Name="Dark List Accent 3"/>\n <w:LsdException Locked="false" Priority="71" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Shading Accent 3"/>\n <w:LsdException Locked="false" Priority="72" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful List Accent 3"/>\n <w:LsdException Locked="false" Priority="73" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Grid Accent 3"/>\n <w:LsdException Locked="false" Priority="60" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Shading Accent 4"/>\n <w:LsdException Locked="false" Priority="61" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light List Accent 4"/>\n <w:LsdException Locked="false" Priority="62" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Grid Accent 4"/>\n <w:LsdException Locked="false" Priority="63" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4"/>\n <w:LsdException Locked="false" Priority="64" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4"/>\n <w:LsdException Locked="false" Priority="65" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 1 Accent 4"/>\n <w:LsdException Locked="false" Priority="66" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 2 Accent 4"/>\n <w:LsdException Locked="false" Priority="67" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4"/>\n <w:LsdException Locked="false" Priority="68" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4"/>\n <w:LsdException Locked="false" Priority="69" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4"/>\n <w:LsdException Locked="false" Priority="70" SemiHidden="false"\n UnhideWhenUsed="false" Name="Dark List Accent 4"/>\n <w:LsdException Locked="false" Priority="71" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Shading Accent 4"/>\n <w:LsdException Locked="false" Priority="72" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful List Accent 4"/>\n <w:LsdException Locked="false" Priority="73" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Grid Accent 4"/>\n <w:LsdException Locked="false" Priority="60" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Shading Accent 5"/>\n <w:LsdException Locked="false" Priority="61" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light List Accent 5"/>\n <w:LsdException Locked="false" Priority="62" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Grid Accent 5"/>\n <w:LsdException Locked="false" Priority="63" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5"/>\n <w:LsdException Locked="false" Priority="64" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5"/>\n <w:LsdException Locked="false" Priority="65" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 1 Accent 5"/>\n <w:LsdException Locked="false" Priority="66" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 2 Accent 5"/>\n <w:LsdException Locked="false" Priority="67" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5"/>\n <w:LsdException Locked="false" Priority="68" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5"/>\n <w:LsdException Locked="false" Priority="69" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5"/>\n <w:LsdException Locked="false" Priority="70" SemiHidden="false"\n UnhideWhenUsed="false" Name="Dark List Accent 5"/>\n <w:LsdException Locked="false" Priority="71" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Shading Accent 5"/>\n <w:LsdException Locked="false" Priority="72" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful List Accent 5"/>\n <w:LsdException Locked="false" Priority="73" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Grid Accent 5"/>\n <w:LsdException Locked="false" Priority="60" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Shading Accent 6"/>\n <w:LsdException Locked="false" Priority="61" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light List Accent 6"/>\n <w:LsdException Locked="false" Priority="62" SemiHidden="false"\n UnhideWhenUsed="false" Name="Light Grid Accent 6"/>\n <w:LsdException Locked="false" Priority="63" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6"/>\n <w:LsdException Locked="false" Priority="64" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6"/>\n <w:LsdException Locked="false" Priority="65" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 1 Accent 6"/>\n <w:LsdException Locked="false" Priority="66" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium List 2 Accent 6"/>\n <w:LsdException Locked="false" Priority="67" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6"/>\n <w:LsdException Locked="false" Priority="68" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6"/>\n <w:LsdException Locked="false" Priority="69" SemiHidden="false"\n UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6"/>\n <w:LsdException Locked="false" Priority="70" SemiHidden="false"\n UnhideWhenUsed="false" Name="Dark List Accent 6"/>\n <w:LsdException Locked="false" Priority="71" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Shading Accent 6"/>\n <w:LsdException Locked="false" Priority="72" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful List Accent 6"/>\n <w:LsdException Locked="false" Priority="73" SemiHidden="false"\n UnhideWhenUsed="false" Name="Colorful Grid Accent 6"/>\n <w:LsdException Locked="false" Priority="19" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis"/>\n <w:LsdException Locked="false" Priority="21" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis"/>\n <w:LsdException Locked="false" Priority="31" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference"/>\n <w:LsdException Locked="false" Priority="32" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Intense Reference"/>\n <w:LsdException Locked="false" Priority="33" SemiHidden="false"\n UnhideWhenUsed="false" QFormat="true" Name="Book Title"/>\n <w:LsdException Locked="false" Priority="37" Name="Bibliography"/>\n <w:LsdException Locked="false" Priority="39" QFormat="true" Name="TOC Heading"/>\n </w:LatentStyles>\n</xml><![endif]--><!--[if gte mso 10]>\n<style>\n /* Style Definitions */\n table.MsoNormalTable\n\t{mso-style-name:"Tableau Normal";\n\tmso-tstyle-rowband-size:0;\n\tmso-tstyle-colband-size:0;\n\tmso-style-noshow:yes;\n\tmso-style-priority:99;\n\tmso-style-parent:"";\n\tmso-padding-alt:0cm 5.4pt 0cm 5.4pt;\n\tmso-para-margin:0cm;\n\tmso-para-margin-bottom:.0001pt;\n\tmso-pagination:widow-orphan;\n\tfont-size:10.0pt;\n\tfont-family:"Times New Roman","serif";}\n</style>\n<![endif]--></p>\n<p class="MsoNormal" style="mso-outline-level: 1;"><strong><span style="font-size: 11.0pt; font-family: \'Calibri\',\'sans-serif\'; mso-ansi-language: FR;" lang="FR">De&nbsp;:</span></strong><span style="font-size: 11.0pt; font-family: \'Calibri\',\'sans-serif\'; mso-ansi-language: FR;" lang="FR"> <a href="mailto:lino@foo.net">lino@foo.net</a> [<a href="mailto:foo@bar.com">mailto:foo@bar.com</a>] <br /> <strong>Envoy&eacute;&nbsp;:</strong> mardi 18 octobre 2016 08:52<br /> <strong>&Agrave;&nbsp;:</strong> <a href="mailto:Far@baz.net">eexample@foo.com</a><br /> <strong>Objet&nbsp;:</strong> [welcht] YOU modified FOO BAR</span></p>\n<p class="MsoNormal">&nbsp;</p>\n<p>Dear Aur&eacute;lie ,</p>\n<p>this is to notify / BAR</p>\n<p>BAR modified </p>\n<p>TODO: include a summary of the modifications.</p>\n<p>Any subsequent notifications about foo/ until you view this notification in the Lino web interface. Please visit</p>\n<p class="MsoNormal"><a href="None">None</a></p>\n<p>and follow your welcome messages.</p>"""
27
+
26
28
  cond_comment = (
27
29
  "<p><!--[if gte foo 123]>A conditional comment<![endif]--></p>\n<p>Hello</p>"
28
30
  )
@@ -67,6 +69,7 @@ def objects():
67
69
  obj.after_ui_create(ses)
68
70
  obj.before_ui_save(ses, None)
69
71
  # obj.full_clean()
72
+ obj.created = now
70
73
  obj.modified = now
71
74
  yield obj
72
75
  obj.after_ui_save(ses, None)
@@ -89,10 +89,9 @@ class AddCommentField(dd.VirtualField):
89
89
 
90
90
 
91
91
  class Commentable(MemoReferrable):
92
- class Meta(object):
93
- abstract = True
94
92
 
95
- create_comment_template = _("Created new {model} {obj}.")
93
+ class Meta:
94
+ abstract = True
96
95
 
97
96
  # add_comment = AddCommentField("comments.CommentsByRFC")
98
97
 
@@ -102,8 +101,8 @@ class Commentable(MemoReferrable):
102
101
  def get_rfc_description(self, ar):
103
102
  return ""
104
103
 
105
- def get_comment_group(self):
106
- return None
104
+ # def get_comment_group(self):
105
+ # return None
107
106
 
108
107
  if dd.is_installed("comments"):
109
108
 
@@ -112,17 +111,17 @@ class Commentable(MemoReferrable):
112
111
  if rt.settings.SITE.loading_from_dump:
113
112
  return
114
113
 
115
- if self.create_comment_template is not None:
116
- txt = self.create_comment_template.format(
117
- model=self.__class__._meta.verbose_name, obj=self
118
- )
119
- # txt = self.get_create_comment(ar)
114
+ if (txt := self.get_create_comment_text(ar)) is not None:
120
115
  comment = rt.models.comments.Comment(body=txt, owner=self)
121
116
  comment.on_create(ar)
122
117
  comment.full_clean()
123
118
  comment.save_new_instance(ar)
124
119
  # print("20220916 save_new_instance() created", comment, txt)
125
120
 
121
+ def get_create_comment_text(self, ar):
122
+ return _("Created new {model} {obj}.").format(
123
+ model=self.__class__._meta.verbose_name, obj=self)
124
+
126
125
  @classmethod
127
126
  def add_comments_filter(cls, qs, ar):
128
127
  return qs
@@ -213,10 +213,10 @@ class Comment(
213
213
  # s += ar.row_as_paragraph(o.owner)
214
214
  s += ar.obj2htmls(o.owner)
215
215
  # s += ar.obj2htmls(o.owner)
216
- if False: # tickets show themselves their group in __str__()
217
- group = o.owner.get_comment_group()
218
- if group and group.ref:
219
- s += "@" + group.ref
216
+ # if False: # tickets show themselves their group in __str__()
217
+ # group = o.owner.get_comment_group()
218
+ # if group and group.ref:
219
+ # s += "@" + group.ref
220
220
 
221
221
  if False and o.num_reactions:
222
222
  txt = ngettext("{} reaction", "{} reactions", o.num_reactions).format(
@@ -118,6 +118,11 @@ class Comments(dd.Table):
118
118
  yield p
119
119
  yield "reply_to"
120
120
 
121
+ @classmethod
122
+ def comments_created(cls, user, sd, ed):
123
+ pv = dict(start_date=sd, end_date=ed, observed_event=CommentEvents.created)
124
+ return cls.request(user=user, param_values=pv)
125
+
121
126
  # @classmethod
122
127
  # def get_card_title(cls, ar, obj):
123
128
  # """Overrides the default behaviour"""
@@ -69,7 +69,7 @@ class Runnable(Sequenced, RecurrenceSet):
69
69
  message = dd.RichTextField(_("Logged messages"), format="plain", editable=False)
70
70
 
71
71
  # procedure = Procedures.field(strict=False, unique=True, editable=False)
72
- procedure = Procedures.field(strict=False, editable=False)
72
+ procedure = Procedures.field(strict=False)
73
73
  name = models.CharField(_("Name"), max_length=200, blank=True)
74
74
 
75
75
  run_now = RunNow()
@@ -203,7 +203,8 @@ async def start_task_runner(ar, max_count=None):
203
203
  nst = await sync_to_async(self.get_next_suggested_date)(
204
204
  self.last_end_time, ar.logger
205
205
  )
206
- next_time = min(next_time, nst)
206
+ if nst is not None:
207
+ next_time = min(next_time, nst)
207
208
 
208
209
  count += 1
209
210
  if max_count is not None and count >= max_count:
@@ -2,8 +2,6 @@
2
2
  # Copyright 2016-2024 Rumma & Ko Ltd
3
3
  # License: GNU Affero General Public License v3 (see file COPYING for details)
4
4
 
5
- from bs4 import BeautifulSoup, NavigableString
6
- from bs4.element import Tag
7
5
  from lxml.html import fragments_fromstring
8
6
  from lino.utils.html import E, tostring, mark_safe
9
7
  import lxml
@@ -22,212 +20,24 @@ from lino.core.gfks import gfk2lookup
22
20
  from lino.core.model import Model
23
21
  from lino.core.fields import fields_list, RichTextField, PreviewTextField
24
22
  from lino.utils.restify import restify
23
+ from lino.utils.soup import truncate_comment
25
24
  from lino.utils.mldbc.fields import BabelTextField
26
25
  from lino.core.exceptions import ChangedAPI
27
26
  from lino.modlib.checkdata.choicelists import Checker
28
27
  from lino.api import rt, dd, _
29
28
 
30
29
 
31
- def old_truncate_comment(html_str, max_p_len=None):
32
- # returns a single paragraph with a maximum number of visible chars.
33
- # No longer used. Replaced by new truncate_comment() below
34
- if max_p_len is None:
35
- max_p_len = settings.SITE.plugins.memo.short_preview_length
36
- html_str = html_str.strip() # remove leading or trailing newlines
37
-
38
- if not html_str.startswith("<"):
39
- if len(html_str) > max_p_len:
40
- txt = html_str[:max_p_len] + "..."
41
- else:
42
- txt = html_str
43
- return txt
44
- soup = BeautifulSoup(html_str, "html.parser")
45
- ps = soup.find_all(
46
- ["p", "h1", "h2", "h3", "h4", "h5", "h6", "h7", "h8", "h9", "pre"]
47
- )
48
- if len(ps) > 0:
49
- anchor_end = "</a>"
50
- txt = ""
51
- for p in ps:
52
- text = ""
53
- for c in p.contents:
54
- if isinstance(c, Tag):
55
- if c.name == "a":
56
- text += str(c)
57
- max_p_len = max_p_len + len(text) - len(c.text)
58
- else:
59
- # text += str(c)
60
- text += c.text
61
- else:
62
- text += str(c)
63
-
64
- if len(txt) + len(text) > max_p_len:
65
- txt += text
66
- if anchor_end in txt:
67
- ae_index = txt.index(anchor_end) + len(anchor_end)
68
- if ae_index >= max_p_len:
69
- txt = txt[:ae_index]
70
- txt += "..."
71
- break
72
- txt = txt[:max_p_len]
73
- txt += "..."
74
- break
75
- else:
76
- txt += text + "\n\n"
77
- return txt
78
- return html_str
79
-
80
-
81
30
  def django_truncate_comment(html_str):
82
31
  # works, but we don't use it because (...)
83
32
  return Truncator(html_str).chars(
84
33
  settings.SITE.plugins.memo.short_preview_length, html=True
85
34
  )
86
35
 
87
-
88
- PARAGRAPH_TAGS = {
89
- "p",
90
- "h1",
91
- "h2",
92
- "h3",
93
- "h4",
94
- "h5",
95
- "h6",
96
- "h7",
97
- "h8",
98
- "h9",
99
- "pre",
100
- "li",
101
- "div",
102
- }
103
- WHITESPACE_TAGS = PARAGRAPH_TAGS | {
104
- "[document]",
105
- "span",
106
- "ul",
107
- "html",
108
- "head",
109
- "body",
110
- "base",
111
- }
112
-
113
-
114
36
  MARKDOWNCFG = dict(
115
37
  extensions=["toc"], extension_configs=dict(toc=dict(toc_depth=3, permalink=True))
116
38
  )
117
39
 
118
40
 
119
- class Style:
120
- # TODO: Extend rstgen.sphinxconf.sigal_image.Format to incoroporate this.
121
- def __init__(self, s):
122
- self._map = {}
123
- if s:
124
- for i in s.split(";"):
125
- k, v = i.split(":", maxsplit=1)
126
- self._map[k.strip()] = v.strip()
127
- self.is_dirty = False
128
-
129
- def __contains__(self, *args):
130
- return self._map.__contains__(*args)
131
-
132
- def __setitem__(self, k, v):
133
- if k in self._map and self._map[k] == v:
134
- return
135
- self._map[k] = v
136
- self.is_dirty = True
137
-
138
- def __delitem__(self, k):
139
- if k in self._map:
140
- self.is_dirty = True
141
- return self._map.__delitem__(k)
142
-
143
- def adjust_size(self):
144
- # if self['float'] == "none":
145
- # return
146
- if "width" in self._map:
147
- del self["width"]
148
- self["height"] = dd.plugins.memo.short_preview_image_height
149
-
150
- def as_string(self):
151
- return ";".join(["{}:{}".format(*kv) for kv in self._map.items()])
152
-
153
-
154
- class TextCollector:
155
- def __init__(self, max_length=None):
156
- self.text = ""
157
- self.sep = "" # becomes "\n\n" after a PARAGRAPH_TAGS
158
- self.remaining = max_length or settings.SITE.plugins.memo.short_preview_length
159
- self.image = None
160
-
161
- def add_chunk(self, ch):
162
- # print("20230712 add_chunk", ch.name, ch)
163
-
164
- if ch.name in WHITESPACE_TAGS:
165
- for c in ch.children:
166
- if not self.add_chunk(c):
167
- return False
168
- if ch.name in PARAGRAPH_TAGS:
169
- self.sep = "\n\n"
170
- else:
171
- self.sep = " "
172
- return True
173
-
174
- assert ch.name != "IMG"
175
-
176
- if ch.name == "img":
177
- if self.image is not None:
178
- # Ignore all images except the first one.
179
- self.text += self.sep
180
- return True
181
- style = Style(ch.get("style", None))
182
- if not "float" in style:
183
- style["float"] = "right"
184
- style.adjust_size()
185
- if style.is_dirty:
186
- ch["style"] = style.as_string()
187
- self.image = ch
188
- # print("20231023 a", ch)
189
-
190
- we_want_more = True
191
- if ch.string is not None:
192
- if len(ch.string) > self.remaining:
193
- # print("20231023", len(ch.string), '>', self.remaining)
194
- ch.string = ch.string[: self.remaining] + "..."
195
- we_want_more = False
196
- # print("20230927", ch.string, ch)
197
- # self.text += str(ch.string) + "..."
198
- # return False
199
- self.remaining -= len(ch.string)
200
-
201
- if isinstance(ch, NavigableString):
202
- self.text += self.sep + ch.string
203
- else:
204
- self.text += self.sep + str(ch)
205
-
206
- self.remaining -= len(self.sep)
207
- self.sep = ""
208
- return we_want_more
209
-
210
-
211
- def truncate_comment(html_str, max_length=300):
212
- # new implementation since 20230713
213
- html_str = html_str.strip() # remove leading or trailing newlines
214
-
215
- if not html_str.startswith("<"):
216
- # print("20231023 c", html_str)
217
- if len(html_str) > max_length:
218
- return html_str[:max_length] + "..."
219
- return html_str
220
-
221
- # if "choose one or the other" in html_str:
222
- # print(html_str)
223
- # raise Exception("20230928 {} {}".format(len(html_str), max_length))
224
-
225
- soup = BeautifulSoup(html_str, "html.parser")
226
- tc = TextCollector(max_length)
227
- tc.add_chunk(soup)
228
- return tc.text
229
-
230
-
231
41
  def rich_text_to_elems(ar, description):
232
42
  if description.startswith("<"):
233
43
  # desc = E.raw('<div>%s</div>' % self.description)
@@ -267,21 +77,16 @@ class MemoReferrable(dd.Model):
267
77
 
268
78
  memo_command = None
269
79
 
270
- @classmethod
271
- def on_analyze(cls, site):
272
- super().on_analyze(site)
80
+ if dd.is_installed("memo"):
273
81
 
274
- if cls.memo_command is None or not site.is_installed("memo"):
275
- return
276
-
277
- mp = site.plugins.memo.parser
278
- mp.register_django_model(cls.memo_command, cls)
279
- # mp.add_suggester("[" + cls.memo_command + " ", cls.objects.all(), 'pk')
280
-
281
- # def get_memo_title(self):
282
- # """A text to be used as title of the ``<a href>``."""
283
- # return None
284
- # return str(self)
82
+ @classmethod
83
+ def on_analyze(cls, site):
84
+ super().on_analyze(site)
85
+ if cls.memo_command is None:
86
+ return
87
+ mp = site.plugins.memo.parser
88
+ mp.register_django_model(cls.memo_command, cls)
89
+ # mp.add_suggester("[" + cls.memo_command + " ", cls.objects.all(), 'pk')
285
90
 
286
91
  def memo2html(self, ar, txt, **kwargs):
287
92
  if txt:
@@ -290,9 +95,6 @@ class MemoReferrable(dd.Model):
290
95
  return tostring(e)
291
96
  # return ar.obj2str(self, **kwargs)
292
97
 
293
- # return "<p>Oops, undefined memo2html()</p>"
294
-
295
- # def obj2memo(self, title=str):
296
98
  def obj2memo(self, text=None):
297
99
  """Render the given database object as memo markup."""
298
100
  if self.memo_command is None:
@@ -8,46 +8,47 @@ from lino.api import dd, rt, _
8
8
 
9
9
 
10
10
  class ChangeNotifier(dd.Model):
11
- class Meta(object):
12
- abstract = True
13
11
 
14
- if dd.is_installed("notify"):
12
+ class Meta:
13
+ abstract = True
15
14
 
16
- def get_change_subject(self, ar, cw):
17
- ctx = dict(user=ar.user, what=str(self))
18
- if cw is None:
19
- return _("{user} created {what}").format(**ctx)
20
- # msg = _("has been created by {user}").format(**ctx)
21
- # return "{} {}".format(self, msg)
22
- if len(list(cw.get_updates())) == 0:
23
- return
24
- return _("{user} modified {what}").format(**ctx)
25
- # msg = _("has been modified by {user}").format(**ctx)
15
+ def get_change_subject(self, ar, cw):
16
+ ctx = dict(user=ar.user, what=str(self))
17
+ if cw is None:
18
+ return _("{user} created {what}").format(**ctx)
19
+ # msg = _("has been created by {user}").format(**ctx)
26
20
  # return "{} {}".format(self, msg)
21
+ if len(list(cw.get_updates())) == 0:
22
+ return
23
+ return _("{user} modified {what}").format(**ctx)
24
+ # msg = _("has been modified by {user}").format(**ctx)
25
+ # return "{} {}".format(self, msg)
26
+
27
+ def get_change_body(self, ar, cw):
28
+ ctx = dict(user=ar.user, what=ar.obj2htmls(self))
29
+ if cw is None:
30
+ html = _("{user} created {what}").format(**ctx)
31
+ html += self.get_change_info(ar, cw)
32
+ html = "<p>{}</p>.".format(html)
33
+ else:
34
+ items = list(cw.get_updates_html(["_user_cache"]))
35
+ if len(items) == 0:
36
+ return
37
+ html = _("{user} modified {what}").format(**ctx)
38
+ html = "<p>{}:</p>".format(html)
39
+ html += tostring(E.ul(*items))
40
+ html += self.get_change_info(ar, cw)
41
+ return "<div>{}</div>".format(html)
42
+
43
+ def get_change_info(self, ar, cw):
44
+ return ""
45
+
46
+ if dd.is_installed("notify"):
27
47
 
28
48
  def add_change_watcher(self, user):
29
49
  pass
30
50
  # raise NotImplementedError()
31
51
 
32
- def get_change_body(self, ar, cw):
33
- ctx = dict(user=ar.user, what=ar.obj2htmls(self))
34
- if cw is None:
35
- html = _("{user} created {what}").format(**ctx)
36
- html += self.get_change_info(ar, cw)
37
- html = "<p>{}</p>.".format(html)
38
- else:
39
- items = list(cw.get_updates_html(["_user_cache"]))
40
- if len(items) == 0:
41
- return
42
- html = _("{user} modified {what}").format(**ctx)
43
- html = "<p>{}:</p>".format(html)
44
- html += tostring(E.ul(*items))
45
- html += self.get_change_info(ar, cw)
46
- return "<div>{}</div>".format(html)
47
-
48
- def get_change_info(self, ar, cw):
49
- return ""
50
-
51
52
  def get_change_owner(self):
52
53
  return self
53
54
 
@@ -7,7 +7,6 @@ from django.utils.translation import gettext_lazy as _
7
7
 
8
8
  from lino.api import dd, rt
9
9
  from lino import mixins
10
- from lino.mixins.periods import DateRange
11
10
  from lino.mixins import Referrable
12
11
 
13
12
  from lino.modlib.office.roles import OfficeStaff