lino 24.11.0__py3-none-any.whl → 25.1.0__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.
- lino/__init__.py +1 -1
- lino/core/actions.py +2 -4
- lino/core/actors.py +35 -14
- lino/core/dbtables.py +12 -12
- lino/core/fields.py +27 -18
- lino/core/inject.py +9 -2
- lino/core/kernel.py +11 -12
- lino/core/model.py +25 -39
- lino/core/renderer.py +3 -4
- lino/core/requests.py +91 -92
- lino/core/site.py +5 -46
- lino/core/store.py +4 -4
- lino/core/tables.py +0 -16
- lino/core/utils.py +5 -2
- lino/help_texts.py +7 -5
- lino/locale/bn/LC_MESSAGES/django.po +1225 -909
- lino/locale/de/LC_MESSAGES/django.mo +0 -0
- lino/locale/de/LC_MESSAGES/django.po +1748 -1392
- lino/locale/django.pot +1150 -909
- lino/locale/es/LC_MESSAGES/django.po +1721 -1347
- lino/locale/et/LC_MESSAGES/django.po +1267 -954
- lino/locale/fr/LC_MESSAGES/django.mo +0 -0
- lino/locale/fr/LC_MESSAGES/django.po +1207 -925
- lino/locale/nl/LC_MESSAGES/django.po +1261 -942
- lino/locale/pt_BR/LC_MESSAGES/django.po +1204 -906
- lino/locale/zh_Hant/LC_MESSAGES/django.po +1204 -906
- lino/mixins/dupable.py +8 -7
- lino/mixins/periods.py +10 -8
- lino/modlib/checkdata/__init__.py +1 -1
- lino/modlib/comments/choicelists.py +1 -1
- lino/modlib/comments/fixtures/demo2.py +4 -1
- lino/modlib/comments/mixins.py +9 -10
- lino/modlib/comments/models.py +4 -4
- lino/modlib/comments/ui.py +11 -2
- lino/modlib/dupable/models.py +10 -14
- lino/modlib/gfks/mixins.py +8 -1
- lino/modlib/jinja/choicelists.py +3 -3
- lino/modlib/jinja/renderer.py +2 -0
- lino/modlib/languages/fixtures/all_languages.py +4 -6
- lino/modlib/linod/mixins.py +3 -2
- lino/modlib/memo/mixins.py +17 -215
- lino/modlib/memo/models.py +41 -12
- lino/modlib/memo/parser.py +7 -3
- lino/modlib/notify/mixins.py +35 -34
- lino/modlib/periods/choicelists.py +46 -0
- lino/modlib/periods/mixins.py +26 -1
- lino/modlib/periods/models.py +17 -45
- lino/modlib/printing/choicelists.py +3 -3
- lino/modlib/publisher/choicelists.py +1 -4
- lino/modlib/search/models.py +17 -11
- lino/modlib/system/fixtures/__init__.py +0 -0
- lino/modlib/system/fixtures/std.py +5 -0
- lino/modlib/system/models.py +3 -2
- lino/modlib/uploads/__init__.py +10 -1
- lino/modlib/uploads/choicelists.py +3 -3
- lino/modlib/uploads/mixins.py +49 -51
- lino/modlib/uploads/models.py +144 -61
- lino/modlib/uploads/ui.py +12 -6
- lino/modlib/uploads/utils.py +113 -0
- lino/modlib/users/mixins.py +9 -6
- lino/modlib/weasyprint/choicelists.py +17 -7
- lino/utils/__init__.py +6 -0
- lino/utils/choosers.py +21 -8
- lino/utils/html.py +1 -1
- lino/utils/instantiator.py +9 -0
- lino/utils/media.py +2 -3
- lino/utils/soup.py +311 -0
- {lino-24.11.0.dist-info → lino-25.1.0.dist-info}/METADATA +2 -2
- {lino-24.11.0.dist-info → lino-25.1.0.dist-info}/RECORD +72 -67
- {lino-24.11.0.dist-info → lino-25.1.0.dist-info}/WHEEL +1 -1
- {lino-24.11.0.dist-info → lino-25.1.0.dist-info}/licenses/AUTHORS.rst +0 -0
- {lino-24.11.0.dist-info → lino-25.1.0.dist-info}/licenses/COPYING +0 -0
lino/modlib/periods/models.py
CHANGED
@@ -8,52 +8,17 @@ from django.utils.translation import gettext_lazy as _
|
|
8
8
|
|
9
9
|
from lino.api import dd
|
10
10
|
from lino import mixins
|
11
|
-
from lino.utils import
|
11
|
+
from lino.utils import ONE_DAY
|
12
12
|
from lino.mixins.periods import DateRange
|
13
13
|
from lino.mixins import Referrable
|
14
14
|
|
15
15
|
from lino.modlib.office.roles import OfficeStaff
|
16
|
+
from .mixins import get_range_for_date
|
17
|
+
from .choicelists import PeriodTypes, PeriodStates
|
16
18
|
|
17
19
|
NEXT_YEAR_SEP = "/"
|
18
20
|
YEAR_PERIOD_SEP = "-"
|
19
21
|
|
20
|
-
class PeriodType(dd.Choice):
|
21
|
-
ref_template = None
|
22
|
-
ref_template = None
|
23
|
-
|
24
|
-
def __init__(self, value, text, duration, ref_template):
|
25
|
-
super().__init__(value, text, value)
|
26
|
-
self.ref_template = ref_template
|
27
|
-
self.duration = duration
|
28
|
-
|
29
|
-
class PeriodTypes(dd.ChoiceList):
|
30
|
-
item_class = PeriodType
|
31
|
-
verbose_name = _("Period type")
|
32
|
-
verbose_name_plural = _("Period types")
|
33
|
-
column_names = "value text duration ref_template"
|
34
|
-
|
35
|
-
@dd.displayfield(_("Duration"))
|
36
|
-
def duration(cls, p, ar):
|
37
|
-
return str(p.duration)
|
38
|
-
|
39
|
-
@dd.displayfield(_("Template for reference"))
|
40
|
-
def ref_template(cls, p, ar):
|
41
|
-
return p.ref_template
|
42
|
-
|
43
|
-
add = PeriodTypes.add_item
|
44
|
-
# value/names, text, duration, ref_template
|
45
|
-
add("month", _("Month"), 1, "{month:0>2}")
|
46
|
-
add("quarter", _("Quarter"), 3, "Q{period}")
|
47
|
-
add("trimester", _("Trimester"), 4, "T{period}")
|
48
|
-
add("semester", _("Semester"), 6, "S{period}")
|
49
|
-
|
50
|
-
|
51
|
-
class PeriodStates(dd.Workflow):
|
52
|
-
pass
|
53
|
-
|
54
|
-
add = PeriodStates.add_item
|
55
|
-
add('10', _("Open"), 'open')
|
56
|
-
add('20', _("Closed"), 'closed')
|
57
22
|
|
58
23
|
|
59
24
|
class StoredYear(DateRange, Referrable):
|
@@ -120,7 +85,7 @@ class StoredPeriod(DateRange, Referrable):
|
|
120
85
|
preferred_foreignkey_width = 10
|
121
86
|
|
122
87
|
state = PeriodStates.field(default='open')
|
123
|
-
year = dd.ForeignKey('periods.StoredYear', blank=True, null=True)
|
88
|
+
year = dd.ForeignKey('periods.StoredYear', blank=True, null=True, related_name="periods")
|
124
89
|
remark = models.CharField(_("Remark"), max_length=250, blank=True)
|
125
90
|
|
126
91
|
@classmethod
|
@@ -197,10 +162,8 @@ class StoredPeriod(DateRange, Referrable):
|
|
197
162
|
ref = date2ref(date)
|
198
163
|
obj = cls.get_by_ref(ref, None)
|
199
164
|
if obj is None:
|
200
|
-
|
201
|
-
|
202
|
-
start_date=date.replace(day=1),
|
203
|
-
end_date=last_day_of_month(date))
|
165
|
+
sd, ed = get_range_for_date(date)
|
166
|
+
obj = cls(ref=ref, start_date=sd, end_date=ed)
|
204
167
|
obj.full_clean()
|
205
168
|
obj.save()
|
206
169
|
return obj
|
@@ -208,7 +171,7 @@ class StoredPeriod(DateRange, Referrable):
|
|
208
171
|
def full_clean(self, *args, **kwargs):
|
209
172
|
if self.start_date is None:
|
210
173
|
self.start_date = dd.today().replace(day=1)
|
211
|
-
if not self.
|
174
|
+
if not self.year_id:
|
212
175
|
self.year = StoredYear.get_or_create_from_date(self.start_date)
|
213
176
|
super().full_clean(*args, **kwargs)
|
214
177
|
|
@@ -218,10 +181,19 @@ class StoredPeriod(DateRange, Referrable):
|
|
218
181
|
# "{0} {1} (#{0})".format(self.pk, self.year)
|
219
182
|
return self.ref
|
220
183
|
|
184
|
+
# def get_str_words(self, ar):
|
185
|
+
# # if ar.is_obvious_field("year"):
|
186
|
+
# if self.year.covers_date(dd.today()):
|
187
|
+
# # yield self.nickname
|
188
|
+
# yield f"{dd.plugins.periods.period_name} {self.nickname}"
|
189
|
+
# else:
|
190
|
+
# yield str(self)
|
191
|
+
|
221
192
|
@property
|
222
193
|
def nickname(self):
|
223
194
|
if self.year.covers_date(dd.today()):
|
224
|
-
if len(parts := self.ref.split(YEAR_PERIOD_SEP)) == 2:
|
195
|
+
if self.ref and len(parts := self.ref.split(YEAR_PERIOD_SEP)) == 2:
|
196
|
+
# return "{} {}".format(dd.plugins.periods.period_name, parts[1])
|
225
197
|
return parts[1]
|
226
198
|
return self.ref
|
227
199
|
|
@@ -46,14 +46,14 @@ class BuildMethod(Choice):
|
|
46
46
|
names, self.__class__.__name__, names, **kwargs
|
47
47
|
)
|
48
48
|
|
49
|
-
def get_target(self, action,
|
50
|
-
|
49
|
+
def get_target(self, action, obj):
|
50
|
+
# Used by get_target_name()
|
51
51
|
# assert self.name is not None
|
52
52
|
return MediaFile(
|
53
53
|
self.use_webdav,
|
54
54
|
self.cache_name,
|
55
55
|
self.value,
|
56
|
-
|
56
|
+
obj.filename_root() + self.target_ext,
|
57
57
|
)
|
58
58
|
|
59
59
|
def get_target_name(self, action, elem):
|
@@ -51,12 +51,9 @@ class PublisherBuildMethod(JinjaBuildMethod):
|
|
51
51
|
)
|
52
52
|
context = elem.get_printable_context(ar)
|
53
53
|
html = tpl.render(context)
|
54
|
-
self.html2file(html, filename)
|
54
|
+
self.html2file(html, filename, context)
|
55
55
|
return os.path.getmtime(filename)
|
56
56
|
|
57
|
-
def html2file(self, html, filename):
|
58
|
-
raise NotImplementedError()
|
59
|
-
|
60
57
|
|
61
58
|
BuildMethods.add_item_instance(PublisherBuildMethod())
|
62
59
|
|
lino/modlib/search/models.py
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
# -*- coding: UTF-8 -*-
|
2
|
-
# Copyright 2021-
|
2
|
+
# Copyright 2021-2024 Rumma & Ko Ltd
|
3
3
|
# License: GNU Affero General Public License v3 (see file COPYING for details)
|
4
4
|
|
5
5
|
import re
|
6
|
-
from html import escape
|
7
6
|
from lxml import etree
|
8
7
|
from django.conf import settings
|
9
8
|
|
@@ -12,7 +11,7 @@ from lino.core import constants
|
|
12
11
|
from lino.core.utils import get_models
|
13
12
|
from lino.core.site import has_elasticsearch, has_haystack
|
14
13
|
|
15
|
-
from lino.utils.html import E
|
14
|
+
from lino.utils.html import E, escape, mark_safe, format_html
|
16
15
|
|
17
16
|
from .roles import SiteSearcher
|
18
17
|
|
@@ -23,15 +22,17 @@ class SiteSearchBase(dd.VirtualTable):
|
|
23
22
|
required_roles = dd.login_required(SiteSearcher)
|
24
23
|
label = _("Search")
|
25
24
|
column_names = "description matches"
|
25
|
+
# column_names = "search_overview matches"
|
26
26
|
private_apps = frozenset(["sessions", "contenttypes", "users"])
|
27
27
|
|
28
|
-
default_display_modes = {None: constants.
|
28
|
+
default_display_modes = {None: constants.DISPLAY_MODE_LIST}
|
29
|
+
# default_display_modes = {None: constants.DISPLAY_MODE_STORY}
|
29
30
|
|
30
31
|
card_layout = """description"""
|
31
|
-
list_layout = """
|
32
|
-
search_overview
|
33
|
-
matches
|
34
|
-
"""
|
32
|
+
# list_layout = """
|
33
|
+
# search_overview
|
34
|
+
# matches
|
35
|
+
# """
|
35
36
|
|
36
37
|
# _site_search_tables = []
|
37
38
|
# @classmethod
|
@@ -76,6 +77,11 @@ class SiteSearchBase(dd.VirtualTable):
|
|
76
77
|
return False
|
77
78
|
return True
|
78
79
|
|
80
|
+
@classmethod
|
81
|
+
def row_as_paragraph(cls, ar, obj):
|
82
|
+
text = "{} #{}".format(obj._meta.verbose_name, obj.pk)
|
83
|
+
return format_html("{} : {}", ar.obj2htmls(obj, text), obj.as_paragraph(ar))
|
84
|
+
|
79
85
|
@dd.displayfield(_("Description"))
|
80
86
|
def description(self, obj, ar):
|
81
87
|
elems = []
|
@@ -110,7 +116,8 @@ class SiteSearchBase(dd.VirtualTable):
|
|
110
116
|
s = matches.get(de, None)
|
111
117
|
if s is None:
|
112
118
|
s = str(de.value_from_object(obj))
|
113
|
-
s = escape(s, quote=False)
|
119
|
+
# s = escape(s, quote=False)
|
120
|
+
s = escape(s)
|
114
121
|
r, count = re.subn(w, bold, s, flags=re.IGNORECASE)
|
115
122
|
if count:
|
116
123
|
matches[de] = r
|
@@ -132,11 +139,10 @@ class SiteSearchBase(dd.VirtualTable):
|
|
132
139
|
raise Exception("{} : {}".format(e, s))
|
133
140
|
# return etree.fromstring(', '.join(chunks))
|
134
141
|
# return E.raw(', '.join(chunks))
|
135
|
-
return s
|
142
|
+
return mark_safe(s)
|
136
143
|
|
137
144
|
|
138
145
|
class SiteSearch(SiteSearchBase):
|
139
|
-
default_display_modes = {None: constants.DISPLAY_MODE_LIST}
|
140
146
|
|
141
147
|
@classmethod
|
142
148
|
def get_data_rows(cls, ar):
|
File without changes
|
lino/modlib/system/models.py
CHANGED
@@ -138,7 +138,7 @@ class SiteConfig(dd.Model):
|
|
138
138
|
# print("20180502 Created SiteConfig {}".format(
|
139
139
|
# obj2str(self._site_config, True)))
|
140
140
|
# 20120725
|
141
|
-
# polls_tutorial menu selection `Config --> Site
|
141
|
+
# polls_tutorial menu selection `Config --> Site configuration`
|
142
142
|
# said "SiteConfig 1 does not exist"
|
143
143
|
# cannot save the instance here because the db table possibly doesn't yet exit.
|
144
144
|
# ~ self._site_config.save()
|
@@ -146,7 +146,7 @@ class SiteConfig(dd.Model):
|
|
146
146
|
return cls._site_config
|
147
147
|
|
148
148
|
def __str__(self):
|
149
|
-
return force_str(_("Site
|
149
|
+
return force_str(_("Site configuration"))
|
150
150
|
|
151
151
|
def update(self, **kw):
|
152
152
|
"""
|
@@ -238,6 +238,7 @@ class SiteConfigs(dd.Table):
|
|
238
238
|
detail_layout = dd.DetailLayout(
|
239
239
|
"""
|
240
240
|
default_build_method
|
241
|
+
simulate_today
|
241
242
|
# lino.ModelsBySite
|
242
243
|
""",
|
243
244
|
window_size=(60, "auto"),
|
lino/modlib/uploads/__init__.py
CHANGED
@@ -9,7 +9,7 @@ from os.path import join
|
|
9
9
|
from lino import ad, _
|
10
10
|
from lino.modlib.memo.parser import split_name_rest
|
11
11
|
|
12
|
-
UPLOADS_ROOT =
|
12
|
+
UPLOADS_ROOT = 'uploads'
|
13
13
|
VOLUMES_ROOT = 'volumes'
|
14
14
|
|
15
15
|
class Plugin(ad.Plugin):
|
@@ -25,6 +25,10 @@ class Plugin(ad.Plugin):
|
|
25
25
|
|
26
26
|
"""
|
27
27
|
|
28
|
+
with_thumbnails = False
|
29
|
+
"""Whether to use PIL, the Python Imaging Library.
|
30
|
+
"""
|
31
|
+
|
28
32
|
# def on_ui_init(self, kernel):
|
29
33
|
# super().on_ui_init(kernel)
|
30
34
|
# self.site.makedirs_if_missing(self.get_uploads_root())
|
@@ -75,3 +79,8 @@ class Plugin(ad.Plugin):
|
|
75
79
|
|
76
80
|
# site.makedirs_if_missing(self.get_uploads_root())
|
77
81
|
# site.makedirs_if_missing(self.get_volumes_root())
|
82
|
+
|
83
|
+
def get_requirements(self, site):
|
84
|
+
if self.with_thumbnails:
|
85
|
+
yield "Pillow"
|
86
|
+
yield "PyMuPDF"
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# -*- coding: UTF-8 -*-
|
2
|
-
# Copyright 2010-
|
2
|
+
# Copyright 2010-2024 Rumma & Ko Ltd
|
3
3
|
# License: GNU Affero General Public License v3 (see file COPYING for details)
|
4
4
|
|
5
|
-
from lino.modlib.office.roles import OfficeStaff
|
6
5
|
from lino.api import dd, rt, _
|
6
|
+
from lino.modlib.office.roles import OfficeStaff
|
7
7
|
|
8
8
|
|
9
9
|
class Shortcut(dd.Choice):
|
@@ -17,7 +17,7 @@ class Shortcut(dd.Choice):
|
|
17
17
|
self.target = target
|
18
18
|
self.model_spec = model_spec
|
19
19
|
value = model_spec + "." + name
|
20
|
-
super(
|
20
|
+
super().__init__(value, verbose_name, name)
|
21
21
|
|
22
22
|
def get_uploads(self, **kw):
|
23
23
|
"""Return a queryset with the uploads of this shortcut."""
|
lino/modlib/uploads/mixins.py
CHANGED
@@ -7,19 +7,24 @@ import shutil
|
|
7
7
|
import uuid
|
8
8
|
from pathlib import Path
|
9
9
|
|
10
|
+
# from rstgen.sphinxconf.sigal_image import parse_image_spec
|
11
|
+
# from rstgen.sphinxconf.sigal_image import Standard, Thumb, Tiny, Wide, Solo, Duo, Trio
|
12
|
+
# SMALL_FORMATS = (Thumb, Tiny, Duo, Trio)
|
13
|
+
#
|
10
14
|
from django.db import models
|
11
15
|
from django.conf import settings
|
12
16
|
from django.core.files.storage import default_storage
|
13
17
|
from django.core.exceptions import ValidationError, FieldError
|
14
18
|
from django.template.defaultfilters import filesizeformat
|
19
|
+
from django.utils.html import format_html
|
15
20
|
|
16
|
-
from rstgen.sphinxconf.sigal_image import parse_image_spec
|
17
21
|
from lino.core import constants
|
18
22
|
from lino.utils import DATE_TO_DIR_TPL
|
23
|
+
from lino.utils import needs_update
|
19
24
|
from lino.utils.html import E
|
20
25
|
from lino.api import dd, rt, _
|
21
26
|
from lino.modlib.uploads import UPLOADS_ROOT
|
22
|
-
from lino.modlib.
|
27
|
+
from lino.modlib.comments.mixins import Commentable
|
23
28
|
|
24
29
|
# from lino.mixins.sequenced import Sequenced
|
25
30
|
# from lino.modlib.gfks.mixins import Controllable
|
@@ -39,12 +44,6 @@ def safe_filename(name):
|
|
39
44
|
return name
|
40
45
|
|
41
46
|
|
42
|
-
def needs_update(src, dest):
|
43
|
-
if dest.exists() and dest.stat().st_mtime >= src.stat().st_mtime:
|
44
|
-
return False
|
45
|
-
return True
|
46
|
-
|
47
|
-
|
48
47
|
def make_uploaded_file(filename, src=None, upload_date=None):
|
49
48
|
"""
|
50
49
|
Create a dummy file that looks as if a file had really been uploaded.
|
@@ -130,8 +129,9 @@ class GalleryViewable(dd.Model):
|
|
130
129
|
return {}
|
131
130
|
|
132
131
|
|
133
|
-
class UploadBase(
|
134
|
-
|
132
|
+
class UploadBase(Commentable, GalleryViewable):
|
133
|
+
|
134
|
+
class Meta:
|
135
135
|
abstract = True
|
136
136
|
|
137
137
|
extra_display_modes = {constants.DISPLAY_MODE_GALLERY}
|
@@ -180,7 +180,8 @@ class UploadBase(MemoReferrable, GalleryViewable):
|
|
180
180
|
dd.logger.info("Wrote uploaded file %s", ff.path)
|
181
181
|
|
182
182
|
def get_gallery_item(self, ar):
|
183
|
-
|
183
|
+
mf = self.get_media_file()
|
184
|
+
return dict(image_src=mf.get_image_url())
|
184
185
|
|
185
186
|
def full_clean(self, *args, **kw):
|
186
187
|
super().full_clean(*args, **kw)
|
@@ -192,44 +193,41 @@ class UploadBase(MemoReferrable, GalleryViewable):
|
|
192
193
|
def get_file_button(self, text=None):
|
193
194
|
if text is None:
|
194
195
|
text = str(self)
|
195
|
-
|
196
|
-
if
|
196
|
+
mf = self.get_media_file()
|
197
|
+
if mf is None:
|
197
198
|
return text
|
198
|
-
return E.a(text, href=
|
199
|
-
|
200
|
-
def memo2html(self, ar, text, **ctx):
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
# print("20230325", rv)
|
235
|
-
return rv
|
199
|
+
return E.a(text, href=mf.get_download_url(), target="_blank")
|
200
|
+
|
201
|
+
# def memo2html(self, ar, text, **ctx):
|
202
|
+
# mf = self.get_media_file()
|
203
|
+
# if mf is None:
|
204
|
+
# return format_html("<em>{}</em>", text or str(self))
|
205
|
+
# ctx.update(src=mf.get_download_url())
|
206
|
+
# ctx.update(href=ar.renderer.obj2url(ar, self))
|
207
|
+
# small_url = mf.get_image_url()
|
208
|
+
# if small_url is None or small_url == mf.url: # non-previewable mimetype
|
209
|
+
# if not text:
|
210
|
+
# text = str(self)
|
211
|
+
# ctx.update(text=text)
|
212
|
+
# tpl = '(<a href="{src}" target="_blank">{text}</a>'
|
213
|
+
# tpl += '| <a href="{href}">detail</a>)'
|
214
|
+
# return format_html(tpl, **ctx)
|
215
|
+
#
|
216
|
+
# fmt = parse_image_spec(text, **ctx)
|
217
|
+
# if isinstance(fmt, SMALL_FORMATS):
|
218
|
+
# fmt.context.update(src=small_url)
|
219
|
+
#
|
220
|
+
# if not fmt.context["caption"]:
|
221
|
+
# fmt.context["caption"] = self.description or str(self)
|
222
|
+
#
|
223
|
+
# rv = format_html(
|
224
|
+
# '<a href="{href}" target="_blank"><img src="{src}"'
|
225
|
+
# + ' style="{style}" title="{caption}"/></a>', **fmt.context)
|
226
|
+
# # if ar.renderer.front_end.media_name == 'react':
|
227
|
+
# # return ('<figure class="lino-memo-image"><img src="{src}" ' +
|
228
|
+
# # 'style="{style}" title="{caption}"/><figcaption' +
|
229
|
+
# # ' style="text-align: center;">{caption}</figcaption>' +
|
230
|
+
# # '</figure>').format(**kwargs)
|
231
|
+
#
|
232
|
+
# # print("20230325", rv)
|
233
|
+
# return rv
|