Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New comment processors - displayDocPartIf and displayWordIf #68

Closed
caring-coder opened this issue Sep 30, 2022 · 3 comments
Closed

New comment processors - displayDocPartIf and displayWordIf #68

caring-coder opened this issue Sep 30, 2022 · 3 comments
Assignees
Labels
enhancement New feature or request question Further information is requested
Milestone

Comments

@caring-coder
Copy link
Member

caring-coder commented Sep 30, 2022

A couple of new comment processors if anyone is interested:

displayWordIf(condition)

You simply stick this comment around a word (or words!) and it will show or hide those words based on whether the condition resolves to true or false

Why is this useful? Let's say you have a scenario where you want to insert a variable, and that variable could be one 3 or more values and the condition comes from a value in your context. Imagine the following sentence

"The surcharge for your delivery will be x dollars"

let's pretend that x isn't available in the context object, but it's value is based on the customer's loyalty level (which is in the context)

Now, we could stick in a replaceWordWith and add a condition like this: (loyaltyLevel == "bronze"? "15": loyaltyLevel == "silver"? : "10": loyaltyLevel == "gold"? "5")

but this approach can get a bit messy for multiple values

Another solution is to write the sentence as "The surcharge for your delivery will be 5 10 15 dollars" and then put a displayWordIf comment around each of the values and the condition within the value as follows displayWordIf(loyaltyLevel == "bronze")

Hope you get the idea.

Anyway the code modification for this is simple. Just stick the following in the DisplayIfProcessor:

	@Override
	public void displayWordIf(Boolean condition) {
		if (!condition) {
			RunUtil.setText(this.getCurrentRunCoordinates().getRun(), "");
		} // otherwise it will just leave the value as is
	}

displayDocPartIf(condition)

So this one is basically a mashup between displayParagraphIf and repeatDocPart

You can select multiple parts of the documents (let's say an entire section containing 5 paragraphs) and add a single comment displayParagraph(condition). If the condition is true, it will show the commented section. If the condition is false, it will hide the commented section.

You can also use this instead of the displayParagraphIf as it also works for single paragraphs.

This is extremely useful. It currently supports paragraphs and tables within the commented section, but you can add any type of object.

Basically, this is the code to do it. A good chunk of it is borrowed from the repeatDocPart comment, so thanks to that contributor.

add the following to the DisplayIfProcessor class

	private List<Object> objectsToBeRemoved = new ArrayList<>();

	@Override
	public void commitChanges() {
		ObjectDeleter deleter = new ObjectDeleter();
		removeParagraphs(deleter);
		removeTables(deleter);
		removeTableRows(deleter);
		removeObjects(deleter);
	}

	@Override
	public void reset() {
		paragraphsToBeRemoved = new ArrayList<>();
		tablesToBeRemoved = new ArrayList<>();
		tableRowsToBeRemoved = new ArrayList<>();
		objectsToBeRemoved = new ArrayList<>();
	}

	@Override
	public void displayDocPartIf(Boolean condition) {
		if (!condition) {
			CommentWrapper commentWrapper = getCurrentCommentWrapper();
			CommentRangeStart start = commentWrapper.getCommentRangeStart();

			ContentAccessor gcp = findGreatestCommonParent(commentWrapper.getCommentRangeEnd(), (ContentAccessor) start.getParent());
			if (gcp instanceof P) {
				paragraphsToBeRemoved.add((P)gcp);
			} else {
				List<Object> repeatElements = getRepeatElements(commentWrapper, gcp);
				objectsToBeRemoved.addAll(repeatElements);
			}
		}
	}

ObjectDeleter.java:

    public void deleteObject(Object object) {
        if (object instanceof P) {
            deleteParagraph((P)object);
        } else {
            Object unwrappedObject = XmlUtils.unwrap(object);
            if (unwrappedObject instanceof Tbl) {
                deleteTable((Tbl) unwrappedObject);
            }
        } // can add more object types here if you like
    }

copied from thombergs/docx-stamper#99

Should we include those ? Why yes or no ?

@dallanmc
Copy link
Contributor

dallanmc commented Oct 7, 2022

I find displayDocPartIf to be very useful for deleting multiple paragraphs and entire sections within documents using just a single comment. It also removes line breaks between paragraphs which I don't think just using displayParagraphIf multiple times would do.

displayWordIf is something I have changed recently to be displayWordsIf (i.e you can have it around multiple words) and I find it very useful for conditional logic within a sentence. e.g. "You have chosen the option green bike | red car | blue scooter" You can have conditional logic around each of those options, which is a bit cleaner than putting all the logic within the comment. There are better use cases for this - I just can't think of them right now !

@caring-coder caring-coder added enhancement New feature or request question Further information is requested labels Oct 7, 2022
@caring-coder caring-coder self-assigned this Nov 21, 2024
@caring-coder caring-coder added this to the 2.7 milestone Nov 21, 2024
@caring-coder
Copy link
Member Author

caring-coder commented Dec 5, 2024

Added the full panoply of displayXXXIf to end up with the following list for version 2.7.0:

display paragraph

  • displayParagraphIfAbsent(object)
  • displayParagraphIf(boolean)
  • displayParagraphIfPresent(object)

display table rows

  • displayTableRowIf(boolean)
  • displayTableRowIfPresent(object)
  • displayTableRowIfAbsent(object)

display tables

  • displayTableIf(boolean)
  • displayTableIfPresent(object)
  • displayTableIfAbsent(object)

display words

  • displayWordsIf(boolean)
  • displayWordsIfPresent(object)
  • displayWordsIfAbsent(object)

display doc parts

  • displayDocPartIf(boolean)
  • displayDocPartIfPresent(object)
  • displayDocPartIfAbsent(object)

While implementing that, noticed htere was bug/regression when paragraph with more than one processors with at least one covering several runs in that paragraph were not executed. It is now fixed, at least in the configuration i found.

@dallanmc
Copy link
Contributor

dallanmc commented Dec 5, 2024

Added the full panoply of displayXXXIf to end up with the following list for version 2.7.0:

display paragraph

  • displayParagraphIfAbsent(object)
  • displayParagraphIf(boolean)
  • displayParagraphIfPresent(object)

display table rows

  • displayTableRowIf(boolean)
  • displayTableRowIfPresent(object)
  • displayTableRowIfAbsent(object)

display tables

  • displayTableIf(boolean)
  • displayTableIfPresent(object)
  • displayTableIfAbsent(object)

display words

  • displayWordsIf(boolean)
  • displayWordsIfPresent(object)
  • displayWordsIfAbsent(object)

display doc parts

  • displayDocPartIf(boolean)
  • displayDocPartIfPresent(object)
  • displayDocPartIfAbsent(object)

While implementing that, noticed htere was bug/regression when paragraph with more than one processors with at least one covering several runs in that paragraph were not executed. It is now fixed, at least in the configuration i found.

Wow! Awesome work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants