Compare commits
6 commits
master
...
order-no-a
Author | SHA1 | Date | |
---|---|---|---|
76ac07742e | |||
f0561bcd71 | |||
d7dc926992 | |||
d20ce9803e | |||
d0699b3716 | |||
a1a68a3fd6 |
12 changed files with 184 additions and 126 deletions
15
app/forms.py
15
app/forms.py
|
@ -37,15 +37,12 @@ class OrderForm(Form):
|
||||||
|
|
||||||
def populate(self) -> None:
|
def populate(self) -> None:
|
||||||
"Fill in the options for courier for an Order"
|
"Fill in the options for courier for an Order"
|
||||||
if current_user.is_admin():
|
|
||||||
self.courier_id.choices = [(0, None)] + [
|
self.courier_id.choices = [(0, None)] + (
|
||||||
(u.id, u.username) for u in User.query.order_by("username")
|
[(u.id, u.username) for u in User.query.order_by("username")] if current_user.is_admin()
|
||||||
]
|
else [(current_user.id, current_user.username)] if current_user.is_authenticated()
|
||||||
else:
|
else []
|
||||||
self.courier_id.choices = [
|
)
|
||||||
(0, None),
|
|
||||||
(current_user.id, current_user.username),
|
|
||||||
]
|
|
||||||
self.location_id.choices = [(l.id, l.name) for l in location_definitions]
|
self.location_id.choices = [(l.id, l.name) for l in location_definitions]
|
||||||
if self.stoptime.data is None:
|
if self.stoptime.data is None:
|
||||||
self.stoptime.data = datetime.now() + timedelta(hours=1)
|
self.stoptime.data = datetime.now() + timedelta(hours=1)
|
||||||
|
|
|
@ -29,10 +29,12 @@ location = >location_header items:{ block } ;
|
||||||
|
|
||||||
|
|
||||||
attributes =
|
attributes =
|
||||||
name:/[^\n#]*?(?= +-- | +:: | +€ | *\n| *#)/
|
name:/[^\n#]*?(?= +-- | | *\n| *#)/
|
||||||
[ s '--' ~ s description:/[^\n#]*?(?= +:: | +€ | *\n| *#)/ ]
|
[ s '--' ~ s description:/[^\n#]*?(?= | *\n| *#)/ ]
|
||||||
[ s '::' {s ('{' tags+:identifier '}')} ]
|
[ / {2,}/ ~
|
||||||
[ [ s '::' ~ ] s price:price ]
|
[ {[ s ] ('{' tags+:identifier '}')} / +|$/ ]
|
||||||
|
[ price:price ]
|
||||||
|
]
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"Script for everything Order related in the database"
|
"Script for everything Order related in the database"
|
||||||
import typing
|
import typing
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
from utils import first
|
from utils import first
|
||||||
from hlds.definitions import location_definitions
|
from hlds.definitions import location_definitions
|
||||||
|
@ -69,23 +70,27 @@ class Order(db.Model):
|
||||||
|
|
||||||
return list(sorted(group.items(), key=lambda t: (t[0] or "", t[1] or "")))
|
return list(sorted(group.items(), key=lambda t: (t[0] or "", t[1] or "")))
|
||||||
|
|
||||||
def group_by_dish(self) -> typing.List[typing.Tuple[str, typing.List]]:
|
def group_by_dish(self) \
|
||||||
|
-> typing.List[typing.Tuple[str, int, typing.List[typing.Tuple[str, typing.List]]]]:
|
||||||
"Group items of an Order by dish"
|
"Group items of an Order by dish"
|
||||||
group: typing.Dict[str, typing.List] = dict()
|
group: typing.Dict[str, typing.Dict[str, typing.List]] = \
|
||||||
|
defaultdict(lambda: defaultdict(list))
|
||||||
|
|
||||||
for item in self.items:
|
for item in self.items:
|
||||||
if item.dish_name not in group:
|
group[item.dish_name][item.comment].append(item)
|
||||||
group[item.dish_name] = []
|
|
||||||
|
|
||||||
group[item.dish_name].append(item)
|
return sorted(
|
||||||
|
(
|
||||||
for _dish_name, order_items in group.items():
|
dish_name,
|
||||||
order_items.sort(key=lambda order_item: (
|
# Amount of items of this dish
|
||||||
(order_item.comment or " No comment") +
|
sum(map(len, comment_group.values())),
|
||||||
(order_item.for_name or "")
|
sorted(
|
||||||
))
|
(comment, sorted(items, key=lambda x: (x.for_name or "")))
|
||||||
|
for comment, items in comment_group.items()
|
||||||
return list(sorted(group.items()))
|
)
|
||||||
|
)
|
||||||
|
for dish_name, comment_group in group.items()
|
||||||
|
)
|
||||||
|
|
||||||
def is_closed(self) -> bool:
|
def is_closed(self) -> bool:
|
||||||
return self.stoptime and datetime.now() > self.stoptime
|
return self.stoptime and datetime.now() > self.stoptime
|
||||||
|
|
|
@ -60,64 +60,6 @@ body {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.showcase {
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 1.2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.showcase {
|
|
||||||
padding: 0;
|
|
||||||
max-width: 500px;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.showcase h1 {
|
|
||||||
font-size: 200%;
|
|
||||||
margin: 0 ;
|
|
||||||
padding: 0.4em 0 0.2em;
|
|
||||||
border-bottom: 1px dashed var(--gray1);
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.showcase h2 {
|
|
||||||
font-size: 110%;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-bottom: 0.6em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.showcase .open-order-warning {
|
|
||||||
font-size: 150%;
|
|
||||||
text-align: center;
|
|
||||||
padding: 1em 0.5em;
|
|
||||||
background-color: rgba(255, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.showcase .dish {
|
|
||||||
padding: 0 0.5em;
|
|
||||||
}
|
|
||||||
@media (min-width: 500px) {
|
|
||||||
.showcase .dish {
|
|
||||||
padding: 0 1em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.showcase .quantity {
|
|
||||||
font-size: 110%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.showcase .comments {
|
|
||||||
padding-left: 2em;
|
|
||||||
}
|
|
||||||
.showcase .comments li {
|
|
||||||
margin: 0.5em 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.showcase .total {
|
|
||||||
border-top: 1px dashed var(--gray1);
|
|
||||||
text-align: center;
|
|
||||||
padding: 0.5em 0;
|
|
||||||
margin-top: 1.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time_data{
|
.time_data{
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
109
app/static/css/shop_view.css
Normal file
109
app/static/css/shop_view.css
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
:root {
|
||||||
|
--bg: #eee;
|
||||||
|
--ticketBg: #fff;
|
||||||
|
--fg: #000;
|
||||||
|
--dashes: 1px dashed #444;
|
||||||
|
--fontFamily: "Roboto","Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||||
|
--fontSize: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: var(--bg);
|
||||||
|
color: var(--fg);
|
||||||
|
font-family: var(--fontFamily);
|
||||||
|
font-size: var(--fontSize);
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticket {
|
||||||
|
background: var(--ticketBg);
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 0;
|
||||||
|
max-width: 500px;
|
||||||
|
margin: 25px auto;
|
||||||
|
margin: 7vh auto;
|
||||||
|
box-shadow: 0 0.15em 0.3em rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 500px) {
|
||||||
|
body {
|
||||||
|
background: var(--ticketBg);
|
||||||
|
}
|
||||||
|
.ticket {
|
||||||
|
margin: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 200%;
|
||||||
|
margin: 0 ;
|
||||||
|
padding: 0.3em 0 0.3em;
|
||||||
|
border-bottom: var(--dashes);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-size: 110%;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 0.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.open-order-warning {
|
||||||
|
font-size: 150%;
|
||||||
|
text-align: center;
|
||||||
|
padding: 1em 0.5em;
|
||||||
|
background-color: rgba(255, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dish {
|
||||||
|
padding: 0 0.5em;
|
||||||
|
}
|
||||||
|
@media (min-width: 500px) {
|
||||||
|
.dish {
|
||||||
|
padding: 0 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity {
|
||||||
|
font-size: 110%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comments {
|
||||||
|
padding-left: 1.5em;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
.comments li {
|
||||||
|
margin: 0.5em 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment_part {
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
padding: 0.1em 0.5em;
|
||||||
|
margin-top: 2px;
|
||||||
|
margin-right: 0.4em;
|
||||||
|
border-radius: 1em;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.comment_part_separator {
|
||||||
|
display: inline-block;
|
||||||
|
width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total {
|
||||||
|
border-top: var(--dashes);
|
||||||
|
text-align: center;
|
||||||
|
padding: 0.5em 0;
|
||||||
|
margin-top: 1.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time_data{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
|
@ -230,24 +230,26 @@
|
||||||
|
|
||||||
<div class="box" id="per_dish">
|
<div class="box" id="per_dish">
|
||||||
<h3>Ordered dishes</h3>
|
<h3>Ordered dishes</h3>
|
||||||
{% for dish_name, dish_order_items in order.group_by_dish() -%}
|
{% for dish_name, dish_quantity, dish_comment_groups in order.group_by_dish() -%}
|
||||||
{% set has_comments = dish_order_items | map(attribute="comment") | any -%}
|
{% set has_comments = dish_comment_groups | length > 1 or (dish_comment_groups | map("first") | any) -%}
|
||||||
<div class="dish {{ 'spacecake no_comments' if not has_comments }}">
|
<div class="dish {{ 'spacecake no_comments' if not has_comments }}">
|
||||||
<h4>
|
<h4>
|
||||||
<span class="quantity">{{ dish_order_items | length }}</span> ×
|
<span class="quantity">{{ dish_quantity }}</span> ×
|
||||||
{{ dish_name }}
|
{{ dish_name }}
|
||||||
</h4>
|
</h4>
|
||||||
|
|
||||||
{% if has_comments -%}
|
{% if has_comments -%}
|
||||||
<ul class="comments">
|
<ul class="comments">
|
||||||
{% for item in dish_order_items -%}
|
{% for comment, items in dish_comment_groups -%}
|
||||||
<li class="spacecake">{% if item["comment"] %}<span>{{ item["comment"] }}</span>
|
<li class="spacecake"><span class="comment">
|
||||||
|
<span class="quantity">{{ items | length }}</span> ×
|
||||||
|
{% if comment %}{{ comment }}
|
||||||
{% else %}<i>No comment</i>
|
{% else %}<i>No comment</i>
|
||||||
{% endif %}<span class="spacer"> </span><span class="item_for">for {{ item.for_name }}</span></li>
|
{% endif %}</span><span class="spacer"> </span><span class="item_for">for {{ items | map(attribute="for_name") | join(", ") }}</span></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="spacer"> </span><span class="item_for">for {{ dish_order_items | map(attribute="for_name") | join(", ") }}</span>
|
<span class="spacer"> </span><span class="item_for">for {{ dish_comment_groups[0][1] | map(attribute="for_name") | join(", ") }}</span>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
|
@ -256,7 +258,7 @@
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
Total {{ order.items.count() }} items — {{ total_price|euro }}
|
Total {{ order.items.count() }} items — {{ total_price|euro }}
|
||||||
|
|
||||||
<a class="btn btn-sm" href="{{ url_for('order_bp.items_showcase', order_id=order.id) }}">Shop view</a>
|
<a class="btn btn-sm" href="{{ url_for('order_bp.items_shop_view', order_id=order.id) }}">Shop view</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -313,9 +315,7 @@
|
||||||
|
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
On selected:
|
On selected:
|
||||||
<button class="btn btn-sm">Mark paid (TODO)</button>
|
<button class="btn btn-sm"><span class="glyphicon glyphicon-ok"></span> Mark paid (TODO)</button>
|
||||||
|
|
||||||
Request payment for selected:
|
|
||||||
<button class="btn btn-sm"><span class="glyphicon glyphicon-piggy-bank"></span> Tab (TODO)</button>
|
<button class="btn btn-sm"><span class="glyphicon glyphicon-piggy-bank"></span> Tab (TODO)</button>
|
||||||
<button class="btn btn-sm"><span class="glyphicon glyphicon-qrcode"></span> QR code (TODO)</button>
|
<button class="btn btn-sm"><span class="glyphicon glyphicon-qrcode"></span> QR code (TODO)</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -439,6 +439,10 @@ li {
|
||||||
color: var(--gray2);
|
color: var(--gray2);
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
#per_dish .comments {
|
||||||
|
padding-left: 1.5em;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#per_person li {
|
#per_person li {
|
||||||
|
@ -472,7 +476,8 @@ li {
|
||||||
|
|
||||||
summary {
|
summary {
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
margin: 0.6em 0;
|
margin: 0 -10px;
|
||||||
|
padding: 4px 10px;
|
||||||
}
|
}
|
||||||
summary .dish_name, summary:before {
|
summary .dish_name, summary:before {
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
|
@ -480,14 +485,16 @@ summary .dish_name, summary:before {
|
||||||
details[open] summary .dish_name {
|
details[open] summary .dish_name {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
details {
|
||||||
|
margin: 0 -10px;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
details[open] {
|
details[open] {
|
||||||
background-color: var(--gray5);
|
background-color: var(--gray5);
|
||||||
margin-left: -10px;
|
padding-bottom: 5px;
|
||||||
margin-right: -10px;
|
}
|
||||||
margin-bottom: 5px;
|
details:not([open]) summary:hover {
|
||||||
padding-left: 10px;
|
background-color: var(--gray5);
|
||||||
padding-right: 10px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
|
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
|
||||||
|
|
|
@ -7,9 +7,7 @@ Haldis - Order {{ order.id }}
|
||||||
|
|
||||||
{% block styles %}
|
{% block styles %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}" media="screen">
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/shop_view.css') }}" media="screen">
|
||||||
<link rel="stylesheet" href="{{ url_for('general_bp.theme_css') }}" media="screen">
|
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/print.css') }}" media="print">
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
|
@ -23,7 +21,7 @@ Haldis - Order {{ order.id }}
|
||||||
{% block content -%}
|
{% block content -%}
|
||||||
{{ utils.flashed_messages(container=True) }}
|
{{ utils.flashed_messages(container=True) }}
|
||||||
|
|
||||||
<div class="darker showcase" id="items-ordered">
|
<div class="ticket" id="items-ordered">
|
||||||
<h1>Haldis order {{ order.id }}</h1>
|
<h1>Haldis order {{ order.id }}</h1>
|
||||||
|
|
||||||
{% if not order.is_closed() %}
|
{% if not order.is_closed() %}
|
||||||
|
@ -33,13 +31,14 @@ Haldis - Order {{ order.id }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% for dish_name, dish_order_items in order.group_by_dish() -%}
|
{% for dish_name, dish_quantity, dish_comment_groups in order.group_by_dish() -%}
|
||||||
<div class="dish">
|
<div class="dish">
|
||||||
<h2><span class="quantity">{{ dish_order_items | length }}</span> × {{ dish_name }}</h2>
|
<h2><span class="quantity">{{ dish_quantity }}</span> × {{ dish_name }}</h2>
|
||||||
{% if dish_order_items | map(attribute="comment") | any -%}
|
{% if dish_comment_groups | map("first") | any -%}
|
||||||
<ul class="comments">
|
<ul class="comments">
|
||||||
{% for item in dish_order_items -%}
|
{% for comment, items in dish_comment_groups -%}
|
||||||
<li>{% if item["comment"] %}{{ item["comment"] }}
|
<li><span class="quantity">{{ items | length }}</span> ×
|
||||||
|
{% if comment %}{{ comment }}
|
||||||
{% else %}<i>No comment</i>
|
{% else %}<i>No comment</i>
|
||||||
{% endif %}</li>
|
{% endif %}</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -14,14 +14,14 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<h4>No orders available.</h4>
|
<h4>No orders available.</h4>
|
||||||
{% if not current_user.is_anonymous() %}
|
{% if form %}
|
||||||
To create an order, fill in the form on the right.
|
To create an order, fill in the form on the right.
|
||||||
{% else %}
|
{% else %}
|
||||||
Login to create an order, or ask someone else.
|
Login to create an order, or ask someone else.
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if not current_user.is_anonymous() %}
|
{% if form %}
|
||||||
<div class="col-md-push-1 col-md-6">
|
<div class="col-md-push-1 col-md-6">
|
||||||
<h3>Create new order</h3>
|
<h3>Create new order</h3>
|
||||||
<div class="row darker">
|
<div class="row darker">
|
||||||
|
|
|
@ -31,7 +31,7 @@ order_bp = Blueprint("order_bp", "order")
|
||||||
@order_bp.route("/")
|
@order_bp.route("/")
|
||||||
def orders(form: OrderForm = None) -> str:
|
def orders(form: OrderForm = None) -> str:
|
||||||
"Generate general order view"
|
"Generate general order view"
|
||||||
if form is None and not current_user.is_anonymous():
|
if form is None:
|
||||||
form = OrderForm()
|
form = OrderForm()
|
||||||
location_id = request.args.get("location_id")
|
location_id = request.args.get("location_id")
|
||||||
form.location_id.default = location_id
|
form.location_id.default = location_id
|
||||||
|
@ -88,7 +88,7 @@ def order_from_id(order_id: int, form: OrderForm = None, dish_id=None) -> str:
|
||||||
|
|
||||||
|
|
||||||
@order_bp.route("/<order_id>/items")
|
@order_bp.route("/<order_id>/items")
|
||||||
def items_showcase(order_id: int) -> str:
|
def items_shop_view(order_id: int) -> str:
|
||||||
"Generate order items view from id"
|
"Generate order items view from id"
|
||||||
order = Order.query.filter(Order.id == order_id).first()
|
order = Order.query.filter(Order.id == order_id).first()
|
||||||
if order is None:
|
if order is None:
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
setlocal noexpandtab
|
setlocal noexpandtab
|
||||||
|
setlocal softtabstop=0
|
||||||
|
|
|
@ -25,8 +25,9 @@ syn keyword hldsChoiceType single_choice multi_choice nextgroup=hldsBlockIdAf
|
||||||
syn match hldsBlockId "^[a-z0-9_-]\+: "
|
syn match hldsBlockId "^[a-z0-9_-]\+: "
|
||||||
syn match hldsBlockIdAftrKywrd "[a-z0-9_-]\+: " contained
|
syn match hldsBlockIdAftrKywrd "[a-z0-9_-]\+: " contained
|
||||||
|
|
||||||
syn match hldsTag " {[a-z0-9_-]\+}"
|
syn match _doubleSpace " \+" nextgroup=hldsTag,hldsPrice
|
||||||
syn match hldsPrice "€ *[0-9]\+\(\.[0-9]\+\|\)"
|
syn match hldsTag "{[a-z0-9_-]\+}\( \|$\)" contained nextgroup=hldsTag,hldsPrice
|
||||||
|
syn match hldsPrice "€ *[0-9]\+\(\.[0-9]\+\|\)\( \|$\)" contained
|
||||||
|
|
||||||
syn match hldsComment "#.*$" contains=hldsTodo,@Spell
|
syn match hldsComment "#.*$" contains=hldsTodo,@Spell
|
||||||
syn keyword hldsTodo FIXME NOTE NOTES TODO XXX contained
|
syn keyword hldsTodo FIXME NOTE NOTES TODO XXX contained
|
||||||
|
|
|
@ -33,13 +33,8 @@
|
||||||
"tags": {
|
"tags": {
|
||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{
|
||||||
"match": "(::)\\s*({[a-zA-Z-_]*}\\s*)*",
|
"match": " +( +{[a-zA-Z-_]*})*",
|
||||||
"name": "markup.italic",
|
"name": "markup.italic"
|
||||||
"captures": {
|
|
||||||
"1": {
|
|
||||||
"name": "markup.bold"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue