From a15e06ef1f53b81f877721609667234325254b68 Mon Sep 17 00:00:00 2001 From: s-heppner Date: Sun, 22 Jun 2025 13:36:31 +0200 Subject: [PATCH] Add new ruleset for `IEEEtran` citation style Previously, we did not draw a precise distinction between the two citation styles `IEEEtran` and `ieeetr` (from `IEEEtran.cls`). This was mainly due to the reason that I did not know myself, that those two were separate styles. This adds a new ruleset for the LaTeX built-in `IEEEtran` citation style. For this, we modify the way the script argument `ruleset` is parsed by allowing to specify the rulesets shipped with the program directly (e.g. by calling it by its name: `bibtex_linter path/to/refs.bib IEEEtran`). However, the default behavior stayed the same, so this change should be backward compatible. Additionally, we adapt the `README.md` accordingly, drawing a more precise disctinction between the `ieeetr` and `IEEEtran` styles. Furthermore, this adds the observations for the styles: `plain`, `apalike` and `IEEEtran` to the `test/test_template` directory. Fixes #12 --- README.md | 13 +- .../{default_rules.py => ieeetr_rules.py} | 0 bibtex_linter/ieeetran_rules.py | 300 ++++++++++++++ bibtex_linter/main.py | 15 +- bibtex_linter/verification.py | 35 ++ ...observations.md => IEEEtr_observations.md} | 17 +- test/test_template/apalike_observations.md | 181 +++++++++ test/test_template/ieeetran_observations.md | 377 ++++++++++++++++++ test/test_template/plain_observations.md | 191 +++++++++ 9 files changed, 1121 insertions(+), 8 deletions(-) rename bibtex_linter/{default_rules.py => ieeetr_rules.py} (100%) create mode 100644 bibtex_linter/ieeetran_rules.py rename test/test_template/{IEEEtran_observations.md => IEEEtr_observations.md} (89%) create mode 100644 test/test_template/apalike_observations.md create mode 100644 test/test_template/ieeetran_observations.md create mode 100644 test/test_template/plain_observations.md diff --git a/README.md b/README.md index 3867ac6..b28aaa0 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,9 @@ As it turns out, a lot of different citation styles omit various fields, and it' Therefore, I created this tool (in Python, since that's what I know best), that can parse the entries and then performs arbitrary (self-defined) invariant checks on them. -In my field the most used citation style is `IEEEtran` so this is how I've defined the default rules of the script. -I've written down the observations on which the rules are based [here](test/test_template/IEEEtran_observations.md). +In my field the most used citation style is `ieeetr` so this is how I've defined the default rules of the script. +I've written down the observations on which the rules are based [here](test/test_template/IEEEtr_observations.md). +These should not be confused with the LaTeX built-in `IEEEtran` citation style, for which I also developed rules. It is however relatively easy to define your own [custom ruleset](#advanced-custom-rulesets), should the need arise. @@ -45,6 +46,14 @@ The script will parse the file, perform the checks and print out the results. > As the `bibtex_linter` returns exit code `0`, if all checks have passed and `1`, if violations were found, > you could also use it in the CI of your LaTeX projects. +### Defined Rulesets +Currently, the following rulesets are shipped with the `bibtex_linter`: + +- `bibtex_linter path/to/refs.bib ieeetr` (default): Citation style of some IEEE conferences (needs `IEEEtran.cls`) +- `bibtex_linter path/to/refs.bib IEEEtran`: LaTeX built-in IEEE citation style (via `\bibliographystyle{IEEEtran}`) + +If you want to define your own rules, see the next section on how to do this: + ### Advanced: Custom Rulesets It is also possible to define your own rules inside a Python file. diff --git a/bibtex_linter/default_rules.py b/bibtex_linter/ieeetr_rules.py similarity index 100% rename from bibtex_linter/default_rules.py rename to bibtex_linter/ieeetr_rules.py diff --git a/bibtex_linter/ieeetran_rules.py b/bibtex_linter/ieeetran_rules.py new file mode 100644 index 0000000..dbf129d --- /dev/null +++ b/bibtex_linter/ieeetran_rules.py @@ -0,0 +1,300 @@ +from typing import List, Set +import re + +from bibtex_linter.parser import BibTeXEntry +from bibtex_linter.verification import ( + linter_rule, + check_required_fields, + check_required_field, + check_omitted_fields, + check_disallowed_field, +) + + +@linter_rule(entry_type=None) +def check_url_field(entry: BibTeXEntry) -> List[str]: + """ + Check that the `url` field is not set. + Additionally, if the `note` field is set, check that it conforms to the following schema: + + ``` + [ONLINE]. Available: \\url{...}, Accessed: YYYY-mmm-dd + ``` + Note, that the backslash had to be escaped here and is only meant to be a single one. + + :param entry: The BibTeXEntry + :return: A list of string descriptions of rule violations for this entry. + """ + invariant_violations: List[str] = [] + if "url" in entry.fields.keys(): + invariant_violations.append( + f"Entry '{entry.name}' contains the non-allowed field: [url]. " + f"Move the content of the field into the [note] field." + ) + if "note" in entry.fields.keys(): + note_content: str = entry.fields["note"] + pattern = r"^\[ONLINE\]\. Available: \\url\{(.+?)\}, Accessed: (\d{4}-\d{2}-\d{2})$" + match = re.match(pattern, note_content) + if not match: + invariant_violations.append( + f"Entry '{entry.name}' contains a malformed field [note]. " + "Make sure the [note] field follows the following pattern: '[ONLINE]. Available: \\url{...}, " + "Accessed: YYYY-mmm-dd'" + ) + return invariant_violations + + +@linter_rule(entry_type="article") +def check_article(entry: BibTeXEntry) -> List[str]: + """ + Check that the article entry type contains the required fields. + + :param entry: The BibTeXEntry + :return: A list of string descriptions of rule violations for this entry. + """ + invariant_violations: List[str] = [] + invariant_violations.extend(check_required_fields( + entry, + fields={ + "author", + "title", + "journal", + "year" + } + )) + return invariant_violations + + +@linter_rule(entry_type="conference") +def check_conference(entry: BibTeXEntry) -> List[str]: + """ + Check that conference entry type contains all required fields. + Additionally, check that 'publisher' and 'organization' are not duplicates of each other. + + :param entry: The BibTeXEntry + :return: A list of string descriptions of rule violations for this entry. + """ + invariant_violations: List[str] = [] + invariant_violations.extend(check_required_fields( + entry, + fields={ + "author", + "title", + "booktitle", + "publisher", + "year", + "type", + } + )) + invariant_violations.extend(check_required_field( + entry, + field="booktitle", + explanation="This should be the name of the conference.", + )) + invariant_violations.extend(check_required_field( + entry, + field="publisher", + explanation="This should be the company that published the proceedings.", + )) + invariant_violations.extend(check_required_field( + entry, + field="type", + explanation="This should describe the type of report/publication (e.g., “Conference Paper”).", + )) + if entry.fields.get("organization") == entry.fields.get("publisher"): + invariant_violations.append( + f"Entry '{entry.name}' fields [organization] and [publisher] are the same. Remove field [organization]." + ) + return invariant_violations + + +@linter_rule(entry_type="online") +def check_online(entry: BibTeXEntry) -> List[str]: + """ + Check that online entry type contains all required fields. + Additionally, check that 'author' and 'organization' are not duplicates of each other. + + :param entry: The BibTeXEntry + :return: A list of string descriptions of rule violations for this entry. + """ + invariant_violations: List[str] = [] + invariant_violations.extend(check_required_fields( + entry, + fields={ + "author", + "title", + "year", + "howpublished", + } + )) + invariant_violations.extend(check_required_field( + entry, + field="howpublished", + explanation="This should be something like: 'White paper', 'Blog post', 'GitHub repository', etc.", + )) + if entry.fields.get("organization") == entry.fields.get("author"): + invariant_violations.append( + f"Entry '{entry.name}' fields [organization] and [author] are the same. Remove field [organization]." + ) + return invariant_violations + + +@linter_rule(entry_type="book") +def check_book(entry: BibTeXEntry) -> List[str]: + """ + Check that book entry type contains all required fields. + Additionally, check that 'publisher' and 'editor' are not duplicates of each other. + + :param entry: The BibTeXEntry + :return: A list of string descriptions of rule violations for this entry. + """ + invariant_violations: List[str] = [] + invariant_violations.extend(check_required_fields( + entry, + fields={ + "author", + "title", + "year", + "publisher", + } + )) + if entry.fields.get("publisher") == entry.fields.get("editor"): + invariant_violations.append( + f"Entry '{entry.name}' fields [publisher] and [editor] are the same. Remove field [editor]." + ) + return invariant_violations + + +@linter_rule(entry_type="inbook") +def check_in_book(entry: BibTeXEntry) -> List[str]: + """ + Check that inbook entry type contains all required fields. + Additionally check that the field `editor` is not present. + + :param entry: The BibTeXEntry + :return: A list of string descriptions of rule violations for this entry. + """ + invariant_violations: List[str] = [] + invariant_violations.extend(check_required_fields( + entry, + fields={ + "author", + "title", + "year", + "publisher", + } + )) + invariant_violations.extend(check_required_field( + entry, + field="title", + explanation="This should be the title of the book.", + )) + invariant_violations.extend(check_disallowed_field( + entry, + field="editor", + explanation="This field is not rendered in IEEEtran-style.", + )) + return invariant_violations + + +@linter_rule(entry_type="incollection") +def check_in_collection(entry: BibTeXEntry) -> List[str]: + """ + Check that incollection entry type contains all required fields. + Additionally, check that the field `type` is not set. + Furthermore, check that 'editor' and 'publisher' are not duplicates of each other. + + :param entry: The BibTeXEntry + :return: A list of string descriptions of rule violations for this entry. + """ + invariant_violations: List[str] = [] + invariant_violations.extend(check_required_fields( + entry, + fields={ + "author", + "title", + "year", + "booktitle", + "publisher", + } + )) + invariant_violations.extend(check_disallowed_field( + entry, + field="type", + explanation="If this field is set to (Article, Paper, Essay etc.), you should use a different entry type." + )) + if entry.fields.get("editor") == entry.fields.get("publisher"): + invariant_violations.append( + f"Entry '{entry.name}' fields [editor] and [publisher] are the same. Remove field [editor]." + ) + return invariant_violations + + +@linter_rule(entry_type="standard") +def check_standard(entry: BibTeXEntry) -> List[str]: + """ + Check that standard entry type contains all required fields. + Furthermore, check that 'author' and 'organization' are not duplicates of each other. + + :param entry: The BibTeXEntry + :return: A list of string descriptions of rule violations for this entry. + """ + invariant_violations: List[str] = [] + invariant_violations.extend(check_required_fields( + entry, + fields={ + "title", + "organization", + "type", + "number", + "year", + } + )) + invariant_violations.extend(check_required_field( + entry, + field="organization", + explanation="This should be the issuing body or standards organization.", + )) + invariant_violations.extend(check_required_field( + entry, + field="type", + explanation="This should be something like " + "(Standard, Technical Report, Recommendation, Specification, Guideline, Draft Standard).", + )) + if entry.fields.get("author") == entry.fields.get("organization"): + invariant_violations.append( + f"Entry '{entry.name}' fields [author] and [organization] are the same. Remove field [author]." + ) + return invariant_violations + + +@linter_rule(entry_type="techreport") +def check_tech_report(entry: BibTeXEntry) -> List[str]: + """ + Disallow the use of the techreport entry type. + + :param entry: The BibTeXEntry + :return: A list of string descriptions of rule violations for this entry. + """ + return [f"Entry '{entry.name}' is of type 'TECHREPORT'. Please use a different entry type, such as 'STANDARD'."] + + +@linter_rule(entry_type="misc") +def check_misc(entry: BibTeXEntry) -> List[str]: + """ + Check that misc entry type contains all required fields. + + :param entry: The BibTeXEntry + :return: A list of string descriptions of rule violations for this entry. + """ + invariant_violations: List[str] = [] + invariant_violations.extend(check_required_fields( + entry, + fields={ + "author", + "title", + "howpublished", + "year", + } + )) + return invariant_violations diff --git a/bibtex_linter/main.py b/bibtex_linter/main.py index 94c8acd..09a29c6 100644 --- a/bibtex_linter/main.py +++ b/bibtex_linter/main.py @@ -31,18 +31,25 @@ def main() -> None: type=str, nargs="?", default=None, - help="Path to the rules.py that define the rules. If left empty, the default ruleset is used. " - "WARNING: Executes the Python code inside rules.py, so be sure that it's safe!") + help="Name (ieeetr, IEEEtran) of or path to the rules.py that define the rules. " + "If left empty, the default ruleset (ieeetr) is used. " + "WARNING: Executes the Python code inside rules.py, so be sure that it's safe! " + "See https://github.com/s-heppner/python-bibtex-linter for more information.") args = parser.parse_args() # Try to import the ruleset if args.ruleset is None: - import bibtex_linter.default_rules + import bibtex_linter.ieeetr_rules print("Using the default ruleset.") else: print(f"Importing rules from {args.ruleset}.") - import_from_path(args.ruleset) + if args.ruleset in ["default", "ieeetr"]: + import bibtex_linter.ieeetr_rules + elif args.ruleset == "IEEEtran": + import bibtex_linter.ieeetran_rules + else: + import_from_path(args.ruleset) entries: List[BibTeXEntry] = parse_bibtex_file(args.filepath) had_violations = False diff --git a/bibtex_linter/verification.py b/bibtex_linter/verification.py index 391af64..35aa030 100644 --- a/bibtex_linter/verification.py +++ b/bibtex_linter/verification.py @@ -42,6 +42,17 @@ def check_required_fields(entry: BibTeXEntry, fields: Set[str]) -> List[str]: return [] +def check_required_field(entry: BibTeXEntry, field: str, explanation: str) -> List[str]: + """ + Helper function to check the existence of one field for the given entry. + If it does not exist, include the explanation sentence in the invariant violation text to help the user fill + out the required field. + """ + if field not in entry.fields.keys(): + return [f"Entry '{entry.name}' misses required field [{field}]. {explanation}"] + return [] + + def check_omitted_fields(entry: BibTeXEntry, fields: Set[str]) -> List[str]: """ Helper function to check the existence of a set of omitted fields for the given entry. @@ -55,6 +66,30 @@ def check_omitted_fields(entry: BibTeXEntry, fields: Set[str]) -> List[str]: return [] +def check_disallowed_fields(entry: BibTeXEntry, fields: Set[str]) -> List[str]: + """ + Helper function to check that no disallowed fields are existing in the given entry. + """ + existing_fields: Set[str] = set(entry.fields.keys()) + disallowed_fields_present = fields & existing_fields + + if disallowed_fields_present: + return [f"Entry '{entry.name}' has fields present that would be omitted in the compiled document: " + f"[{', '.join(sorted(disallowed_fields_present))}]."] + return [] + + +def check_disallowed_field(entry: BibTeXEntry, field: str, explanation: str) -> List[str]: + """ + Helper function to check the existence of a disallowed one field for the given entry. + If it does exist, include the explanation sentence in the invariant violation text to help the user understand + why it is disallowed. + """ + if field not in entry.fields.keys(): + return [f"Entry '{entry.name}' contains disallowed field [{field}]. {explanation}"] + return [] + + def verify(entry: BibTeXEntry) -> List[str]: """ Call this function to execute all imported methods that have the `invariant` decorator. diff --git a/test/test_template/IEEEtran_observations.md b/test/test_template/IEEEtr_observations.md similarity index 89% rename from test/test_template/IEEEtran_observations.md rename to test/test_template/IEEEtr_observations.md index 48b1e84..8ecc1cd 100644 --- a/test/test_template/IEEEtran_observations.md +++ b/test/test_template/IEEEtr_observations.md @@ -1,5 +1,18 @@ -## IEEE Citations -Here's my observations on the different entry types with the standard `IEEEtran.cls` style template. +## IEEEtr Style +Here's my observations on the different entry types with the standard `IEEEtran.cls` style template used in some +IEEE conferences. + +> [!warning] +> This is not to be confused with the built-in LaTeX `ieeetran` style + +This snippet used together with the `IEEEtran.cls` file to create the citations for the observations: + +```latex +\bibliographystyle{ieeetr} +\bibliography{maximal_example_refs.bib} +\nocite{*} +``` + You can find maximal examples (e.g. of all the available fields) [here](./test/test_template/maximal_example_refs.bib). This file can also be used to generate a test bibliography to check how entries are rendered with your citation style and template. diff --git a/test/test_template/apalike_observations.md b/test/test_template/apalike_observations.md new file mode 100644 index 0000000..e910f2e --- /dev/null +++ b/test/test_template/apalike_observations.md @@ -0,0 +1,181 @@ +# APA Citation Style +Here are my observations using the `apalike` citation style. +The following snippet was used and compiled with `lualatex`: + +```latex +\bibliographystyle{apalike} +\bibliography{maximal_example_refs.bib} +\nocite{*} +``` + +# Article +Rendered fields +- author +- year +- title +- journal +- volume +- number +- pages +- note + +Not rendered fields +- language +- month +- url + +# Conference/InProceedings +Rendered fields +- author +- year +- title +- editor +- booktitle +- volume +- series +- pages +- address +- organization +- publisher +- note + +Not rendered fields +- intype +- language +- number +- month +- paper +- type +- url + +# Online +Rendered fields +- author +- year +- title +- howpublished +- note + +Not rendered fields +- language +- organization +- address +- url +- month + +# Book +Rendered fields +- author +- year +- title +- volume +- series +- publisher +- address +- organization +- publisher +- note + +Not rendered fields +- editor +- language +- edition +- month +- number +- url + +# InBook +Rendered fields +- author +- year +- title +- volume +- series +- type +- chapter +- pages +- publisher +- address +- edition +- note + +Not rendered fields +- editor +- language +- month +- number +- url + +# InCollection +Rendered fields +- author +- year +- title +- editor +- booktitle +- volume +- series +- type +- chapter +- pages +- publisher +- address +- edition +- note + +Not rendered fields +- language +- month +- number +- chapter +- url + +# Standard +Rendered fields +- author +- year +- title +- howpublished +- note + +Not rendered fields +- language +- institution +- address +- number +- type +- month +- url + +# TechReport +Rendered fields +- author +- year +- title +- type +- number +- institution +- address +- note + +Not rendered fields +- language +- howpublished +- month +- url + +# Misc +Rendered fields +- author +- year +- title +- howpublished +- note + +Not rendered fields +- language +- organization +- address +- pages +- month +- url diff --git a/test/test_template/ieeetran_observations.md b/test/test_template/ieeetran_observations.md new file mode 100644 index 0000000..07586e2 --- /dev/null +++ b/test/test_template/ieeetran_observations.md @@ -0,0 +1,377 @@ +# IEEEtran Citation Style +Here are my observations using the `ieeetran` citation style. +The following snippet was used and compiled with `lualatex`: + +```latex +\bibliographystyle{IEEEtran} +\bibliography{maximal_example_refs.bib} +\nocite{*} +``` + +# Special Rules +- if an `url`-field is present, we raise an error. We rather expect to use a note field with the following schema: + `[ONLINE]. Available: \url{}, Accessed: YYYY-mm-dd`. + + +# Article +An article in a journal. + +Volume vs number: +- `volume`: Groups all issues published in a year. +- `number`: (or Issue) – Specific issue within a volume. +- some journals don’t use issue numbers, only volumes. +- Online-only or open access journals may skip both . + +Based on the observations below, we define the following rules: +- Mandatory fields + - author + - title + - journal + - year +- Optional fields + - volume + - number + - pages + - month +- Disallowed fields: + - url +- Special rules (see above) + - `note` and `url` (see above) + +Rendered fields +- author +- title +- journal +- volume +- number +- pages +- month +- year +- note +- url + +Not rendered fields +- language + +# Conference/InProceedings +A conference article + +Based on the observations below, we define the following rules: +- Mandatory fields: + - author + - title + - booktitle + - publisher + - year + - type +- Optional fields: + - series + - editor + - volume + - number + - organization + - address + - month + - pages + - note +- Not allowed fields: + - paper + - url +- Special Rules: + - If both `organization` and `publisher` have the exact same value, only use `publisher`. + - `note` and `url` (see above) + +Rendered fields +- author +- title +- intype (Not really standard, avoid using) +- booktitle (Name of the conference) +- series (For conferences published in a recurring series (e.g., Lecture Notes in Computer Science), optional) +- editor (The people who compiled/edited the proceedings volume. Optional) +- volume (If part of a multi-volume proceedings (e.g., Volume 2 of a conference series), uncommon, optional.) +- number (Usually the issue number in a journal. Rarely needed for conference proceedings, optional) +- organization (The body hosting the conference) +- address (The people who compiled/edited the proceedings volume, optional.) +- publisher (The company that published the proceedings (e.g., IEEE Press, Springer).) +- month +- year +- type (Describes the type of report/publication (e.g., “Conference Paper”)) +- paper (Not standard, avoid using) +- pages +- note +- url + +Not rendered fields +- language + +# Online/Electronic +A reference on the internet. + +Based on the observations below, we define the following rules: +- Mandatory fields + - author + - year + - title + - howpublished (Something like: "White paper", "Blog post", "GitHub Repository", etc.) +- Optional fields: + - month + - organization + - address + - note +- Disallowed fields: + - url +- Special rules: + - `note` and `url` (see above) + - If `organization` and `author` are the same, only use `author` + +Rendered fields +- author +- year +- month +- title +- howpublished +- organization +- address +- note +- url + +Not rendered fields +- language + +# Book +Referencing a whole book. + +Based on the observations below, we define the following rules: +- Mandatory fields: + - author + - title + - publisher + - year +- Optional fields: + - edition + - series + - editor + - address + - month + - volume + - number + - note +- Disallowed fields: + - url +- Special rules: + - `note` and `url` (see above) + - If `editor` and `publisher` are the same, only use `publisher`. + +Rendered fields +- author +- title +- edition +- series +- editor +- address +- publisher +- month +- year +- volume +- number +- note +- url + +Not rendered fields +- language + +# InBook +Referencing a part of a book (chapters or pages). + +Based on the observations below, we define the following rules: +- Mandatory fields: + - author + - title (of the book) + - publisher + - year +- Optional fields: + - edition + - series + - address + - month + - volume + - number + - type (One of: "Chapter", "Section", "Appendix", "Part") + - chapter + - pages + - note +- Disallowed fields: + - url + - editor (not rendered) +- Special rules: + - `note` and `url` (see above) + +Rendered fields +- author +- title +- edition +- series +- address +- publisher +- month +- year +- volume +- number +- type +- chapter +- pages +- note +- url + +Not rendered fields +- editor +- language + +# InCollection +Referencing a part of a book that has its own name. + +Based on the observations below, we define the following rules: +- Mandatory fields: + - author + - title + - booktitle + - publisher + - year +- Optional fields: + - edition + - series + - editor + - address + - month + - chapter + - pages + - note +- Disallowed fields: + - url + - type (Since if it was set to (Article, Paper, Essay etc.), we should use ARTICLE or CONFERENCE instead.) +- Special rules: + - `note` and `url` (see above) + - If `editor` and `publisher` are the same, use `publisher`. + +Rendered fields +- author +- title +- booktitle +- edition +- series +- editor +- address +- publisher +- month +- year +- volume +- number +- type +- chapter +- pages +- note +- url + +Not rendered fields +- language + +# Standard +Used for proposed or formally published standards. + +Based on the observations below, we define the following rules: +- Mandatory fields: + - title + - organization (The issuing body or standards organization) + - type (Standard, Technical Report, Recommendation, Specification, Guideline, Draft Standard) + - number + - year +- Optional fields: + - author + - howpublished (how the standard is delivered or accessed "Online", "Print", "PDF", "Available from IEEE Xplore") + - revision + - month + - note +- Disallowed fields: + - url +- Special rules: + - `note` and `url` (see above) + - If `author` and `organization` are the same, use `organization` + +Rendered fields +- author +- title +- howpublished +- organization +- type +- number +- revision +- month +- year +- note +- url + +Not rendered fields +- language +- institution +- address + +# TechReport +Used for technical reports, or reports about standards. Not to be confused with +[standard](#standard). + +> [!note] +> I advise against using `techreport`. Rather use `standard` instead. + +Rendered fields +- author +- title +- howpublished +- institution +- address +- type +- number +- month +- year +- note +- url + +Not rendered fields +- language + +# Misc +Anything else that does not fit the above. + +Based on the observations below, we define the following rules: +- Mandatory fields: + - author + - title + - howpublished + - year +- Optional fields: + - organization + - address + - pages + - month + - note +- Disallowed fields: + - url +- Special rules: + - `note` and `url` (see above) + +> [!note] +> Try using the other entry types instead of this one, if possible. + +Rendered fields +- author +- title +- howpublished +- organization +- address +- pages +- month +- year +- note +- url + +Not rendered fields +- language diff --git a/test/test_template/plain_observations.md b/test/test_template/plain_observations.md new file mode 100644 index 0000000..899a130 --- /dev/null +++ b/test/test_template/plain_observations.md @@ -0,0 +1,191 @@ +# Plain (Numbered) Citation Style +Here are my observations using the `plain` citation style. +The following snippet was used and compiled with `lualatex`: + +```latex +\bibliographystyle{plain} +\bibliography{maximal_example_refs.bib} +\nocite{*} +``` + +> [!note] +> The following observations are also valid for the `alpha` and `abbrv` styles. +> They should also be valid for `unsrt` style. + +# Article +Rendered fields +- author +- title +- journal +- volume +- number +- pages +- month +- year +- note + +Not rendered fields +- language +- url + +# Conference/InProceedings +Based on the observations below, I'd suggest to use +- `editor` as name of the conference +- `organization` as the organization e.g IEEE IES +- `publisher` as the publisher, but only one of the two if both are the same + +Rendered fields +- author +- title +- editor (as "In") +- booktitle +- volume +- series +- pages +- address +- month +- year +- organization +- publisher +- note + +Not rendered fields +- intype +- booktitle +- language +- number +- paper +- type +- url + +# Online +Rendered fields +- author +- title +- howpublished +- month +- year +- note + +Not rendered fields +- language +- organization +- address +- url + +# Book +Rendered fields +- author +- title +- volume +- series +- publisher +- address +- edition +- month +- year +- note + +Not rendered fields +- editor +- language +- number +- url + +# InBook +Rendered fields +- author +- title +- volume +- series +- type +- chapter +- pages +- publisher +- address +- edition +- month +- year +- note + +Not rendered fields +- editor +- language +- number +- url + +# InCollection +Rendered fields +- author +- title +- editor +- booktitle +- volume +- series +- type +- chapter +- pages +- publisher +- address +- edition +- month +- year +- note + +Not rendered fields +- language +- number +- url + +# Standard +Rendered fields +- author +- title +- howpublished +- month +- year +- note + +Not rendered fields +- language +- organization +- institution +- type +- number +- revision +- address +- url + +# TechReport +Rendered fields +- author +- title +- type +- number +- institution +- address +- month +- year +- note + +Not rendered fields +- language +- howpublished +- address +- url + +# Misc +Rendered fields +- author +- title +- howpublished +- month +- year +- note + +Not rendered fields +- language +- organization +- address +- pages +- url