Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ The application allows you to automate the process of generating a bibliography

Supported citation styles:
- ГОСТ Р 7.0.5-2008
- APA

## Installation

Expand Down
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

Поддерживаемые стили цитирования:
- ГОСТ Р 7.0.5-2008
- APA

Установка
=========
Expand Down
55 changes: 54 additions & 1 deletion src/formatters/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ class InternetResourceModel(BaseModel):


class ArticlesCollectionModel(BaseModel):

"""
Модель сборника статей:

Expand All @@ -78,3 +77,57 @@ class ArticlesCollectionModel(BaseModel):
publishing_house: str
year: int = Field(..., gt=0)
pages: str


class RegulatoryActModel(BaseModel):
"""
Модель нормативного акта:
.. code-block::
RegulatoryActModel(
type="Трудовой кодекс",
name="Наука как искусство",
agree_date="02.01.2022",
act_num="8888-88",
publishing_source="Сайт России",
year=2022,
source=5,
article=15,
amended_from="01.01.2021",
)
"""

type: str
name: str
agree_date: str
act_num: str
publishing_source: str
year: int = Field(..., gt=0)
source: int = Field(..., gt=0)
article: int = Field(..., gt=0)
amended_from: str


class DissertationModel(BaseModel):
"""
Модель диссертации:
.. code-block::
DissertationModel(
author_name="Петров С.Н.",
title="Наука как искусство",
author_title="канд.",
special_field="ЭВМ.",
special_code="09.01.02",
city="СПб.",
year=2022,
pages=199,
)
"""

author_name: str = Field(..., min_length=1)
title: str = Field(..., min_length=1)
author_title: str = Field(..., min_length=1)
special_field: str = Field(..., min_length=1)
special_code: str = Field(..., min_length=1)
city: str = Field(..., min_length=1)
year: int = Field(..., gt=0)
pages: int = Field(..., gt=0)
197 changes: 197 additions & 0 deletions src/formatters/styles/apa.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
"""
Стиль цитирования по APA 7.
"""
from string import Template

from pydantic import BaseModel

from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel, RegulatoryActModel, DissertationModel
from formatters.styles.base import BaseCitationStyle
from logger import get_logger


logger = get_logger(__name__)


class APABook(BaseCitationStyle):

data: BookModel

@property
def template(self) -> Template:
return Template(
"$authors. ($year). $title $edition. $publishing_house."
)

def substitute(self) -> str:

logger.info('Форматирование книги "%s" ...', self.data.title)

return self.template.substitute(
authors=self.data.authors,
title=self.data.title,
edition=self.get_edition(),
city=self.data.city,
publishing_house=self.data.publishing_house,
year=self.data.year,
)

def get_edition(self) -> str:


if self.data.edition:
ed = int(self.data.edition.split("-")[0])
res = f"{ed}th"
if 10 <= ed % 100 <=19:
res = f"{ed}th"
elif ed % 10 == 1:
res = f"{ed}st"
elif ed % 10 == 2:
res = f"{ed}nd"
elif ed % 10 == 3:
res = f"{ed}rd"
return f" ({res} ed.)"
return ""


class APAInternetResource(BaseCitationStyle):
"""
Форматирование для интернет-ресурсов.
"""

data: InternetResourceModel

@property
def template(self) -> Template:
return Template(
'$article. $website. (n.d.). $link'
)

def substitute(self) -> str:
logger.info('Форматирование интернет-ресурса "%s" ...', self.data.article)

return self.template.substitute(
article=self.data.article,
website=self.data.website,
link=self.data.link,
)


class APACollectionArticle(BaseCitationStyle):
"""
Форматирование для статьи из сборника.
"""

data: ArticlesCollectionModel

@property
def template(self) -> Template:
return Template(
'$authors ($year). $article_title, $collection_title. (pp. $pages). $publishing_house.'
)

def substitute(self) -> str:

logger.info('Форматирование сборника статей "%s" ...', self.data.article_title)

return self.template.substitute(
authors=self.data.authors,
article_title=self.data.article_title,
collection_title=self.data.collection_title,
publishing_house=self.data.publishing_house,
year=self.data.year,
pages=self.data.pages,
)





class APARegulatoryAct(BaseCitationStyle):
"""
Форматирование для нормативного акта.
"""

data: RegulatoryActModel

@property
def template(self) -> Template:
return Template(
'$name, $act_num $publishing_source. § $article ($year).'
)

def substitute(self) -> str:

logger.info('Форматирование нормативного акта "%s" ...', self.data.name)

return self.template.substitute(
name=self.data.name,
publishing_source=self.data.publishing_source,
act_num=self.data.act_num,
article=self.data.article,
year=self.data.year,
)


class APADissertation(BaseCitationStyle):
"""
Форматирование для диссертации.
"""

data: DissertationModel

@property
def template(self) -> Template:
return Template(
"$author_name ($year) $title, дис. [$author_title $special_field $special_code] $city, $pages с."
)

def substitute(self) -> str:

logger.info('Форматирование диссертации "%s" ...', self.data.title)

return self.template.substitute(
author_name=self.data.author_name,
title=self.data.title,
author_title=self.data.author_title,
special_field=self.data.special_field,
special_code=self.data.special_code,
city=self.data.city,
year=self.data.year,
pages=self.data.pages,
)


class APACitationFormatter:
"""
Базовый класс для итогового форматирования списка источников.
"""

formatters_map = {
BookModel.__name__: APABook,
InternetResourceModel.__name__: APAInternetResource,
ArticlesCollectionModel.__name__: APACollectionArticle,
RegulatoryActModel.__name__: APARegulatoryAct,
DissertationModel.__name__: APADissertation,

}

def __init__(self, models: list[BaseModel]) -> None:
"""
Конструктор.
:param models: Список объектов для форматирования
"""

formatted_items = []
for model in models:
formatted_items.append(self.formatters_map.get(type(model).__name__)(model)) # type: ignore

self.formatted_items = formatted_items

def format(self) -> list[BaseCitationStyle]:
"""
Форматирование списка источников.
:return:
"""

return sorted(self.formatted_items, key=lambda item: item.formatted)
66 changes: 61 additions & 5 deletions src/formatters/styles/gost.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

from pydantic import BaseModel

from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel
from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel, RegulatoryActModel, \
DissertationModel
from formatters.styles.base import BaseCitationStyle
from logger import get_logger


logger = get_logger(__name__)


Expand All @@ -27,7 +27,6 @@ def template(self) -> Template:
)

def substitute(self) -> str:

logger.info('Форматирование книги "%s" ...', self.data.title)

return self.template.substitute(
Expand Down Expand Up @@ -64,7 +63,6 @@ def template(self) -> Template:
)

def substitute(self) -> str:

logger.info('Форматирование интернет-ресурса "%s" ...', self.data.article)

return self.template.substitute(
Expand All @@ -89,7 +87,6 @@ def template(self) -> Template:
)

def substitute(self) -> str:

logger.info('Форматирование сборника статей "%s" ...', self.data.article_title)

return self.template.substitute(
Expand All @@ -103,6 +100,63 @@ def substitute(self) -> str:
)


class GOSTRegulatoryAct(BaseCitationStyle):
"""
Форматирование для нормативного акта.
"""

data: RegulatoryActModel

@property
def template(self) -> Template:
return Template(
'$type "$name" от $agree_date №$act_num // $publishing_source, $year. – №$source – Ст. $article с изм. и допол. в ред. от $amended_from.'
)

def substitute(self) -> str:
logger.info('Форматирование нормативного акта "%s" ...', self.data.name)

return self.template.substitute(
type=self.data.type,
name=self.data.name,
agree_date=self.data.agree_date,
act_num=self.data.act_num,
publishing_source=self.data.publishing_source,
year=self.data.year,
source=self.data.source,
article=self.data.article,
amended_from=self.data.amended_from,
)


class GOSTDissertation(BaseCitationStyle):
"""
Форматирование для диссертации.
"""

data: DissertationModel

@property
def template(self) -> Template:
return Template(
"$author_name $title: дис. $author_title $special_field: $special_code $city $year. $pages c."
)

def substitute(self) -> str:
logger.info('Форматирование диссертации "%s" ...', self.data.title)

return self.template.substitute(
author_name=self.data.author_name,
title=self.data.title,
author_title=self.data.author_title,
special_code=self.data.special_code,
special_field=self.data.special_field,
city=self.data.city,
year=self.data.year,
pages=self.data.pages
)


class GOSTCitationFormatter:
"""
Базовый класс для итогового форматирования списка источников.
Expand All @@ -112,6 +166,8 @@ class GOSTCitationFormatter:
BookModel.__name__: GOSTBook,
InternetResourceModel.__name__: GOSTInternetResource,
ArticlesCollectionModel.__name__: GOSTCollectionArticle,
RegulatoryActModel.__name__: GOSTRegulatoryAct,
DissertationModel.__name__: GOSTDissertation,
}

def __init__(self, models: list[BaseModel]) -> None:
Expand Down
Loading